blob: 843e19fe8a6784fd0b752103f28c322e8222fe19 [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001#
2# SPDX-License-Identifier: MIT
3#
4
Patrick Williamsc124f4f2015-09-15 14:41:29 -05005import os
6import sys
Andrew Geisslerc926e172021-05-07 16:11:35 -05007import json
Patrick Williamsc124f4f2015-09-15 14:41:29 -05008import errno
9import datetime
10import itertools
Patrick Williamsc0f7c042017-02-23 20:41:17 -060011from .commands import runCmd
Patrick Williamsc124f4f2015-09-15 14:41:29 -050012
Patrick Williamsc124f4f2015-09-15 14:41:29 -050013class BaseDumper(object):
14 """ Base class to dump commands from host/target """
15
16 def __init__(self, cmds, parent_dir):
17 self.cmds = []
Patrick Williamsf1e5d692016-03-30 15:21:19 -050018 # Some testing doesn't inherit testimage, so it is needed
19 # to set some defaults.
Brad Bishop977dc1a2019-02-06 16:01:43 -050020 self.parent_dir = parent_dir
Patrick Williamsf1e5d692016-03-30 15:21:19 -050021 dft_cmds = """ top -bn1
22 iostat -x -z -N -d -p ALL 20 2
23 ps -ef
24 free
25 df
26 memstat
27 dmesg
28 ip -s link
29 netstat -an"""
Patrick Williamsc124f4f2015-09-15 14:41:29 -050030 if not cmds:
Patrick Williamsf1e5d692016-03-30 15:21:19 -050031 cmds = dft_cmds
Patrick Williamsc124f4f2015-09-15 14:41:29 -050032 for cmd in cmds.split('\n'):
33 cmd = cmd.lstrip()
34 if not cmd or cmd[0] == '#':
35 continue
36 self.cmds.append(cmd)
37
38 def create_dir(self, dir_suffix):
39 dump_subdir = ("%s_%s" % (
40 datetime.datetime.now().strftime('%Y%m%d%H%M'),
41 dir_suffix))
42 dump_dir = os.path.join(self.parent_dir, dump_subdir)
43 try:
44 os.makedirs(dump_dir)
45 except OSError as err:
46 if err.errno != errno.EEXIST:
47 raise err
48 self.dump_dir = dump_dir
49
50 def _write_dump(self, command, output):
51 if isinstance(self, HostDumper):
52 prefix = "host"
53 elif isinstance(self, TargetDumper):
54 prefix = "target"
Andrew Geisslerc926e172021-05-07 16:11:35 -050055 elif isinstance(self, MonitorDumper):
56 prefix = "qmp"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050057 else:
58 prefix = "unknown"
59 for i in itertools.count():
60 filename = "%s_%02d_%s" % (prefix, i, command)
61 fullname = os.path.join(self.dump_dir, filename)
62 if not os.path.exists(fullname):
63 break
Andrew Geisslerc926e172021-05-07 16:11:35 -050064 if isinstance(self, MonitorDumper):
65 with open(fullname, 'w') as json_file:
66 json.dump(output, json_file, indent=4)
67 else:
68 with open(fullname, 'w') as dump_file:
69 dump_file.write(output)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050070
71class HostDumper(BaseDumper):
72 """ Class to get dumps from the host running the tests """
73
74 def __init__(self, cmds, parent_dir):
75 super(HostDumper, self).__init__(cmds, parent_dir)
76
77 def dump_host(self, dump_dir=""):
78 if dump_dir:
79 self.dump_dir = dump_dir
Andrew Geissler82c905d2020-04-13 13:39:40 -050080 env = os.environ.copy()
81 env['PATH'] = '/usr/sbin:/sbin:/usr/bin:/bin'
82 env['COLUMNS'] = '9999'
Patrick Williamsc124f4f2015-09-15 14:41:29 -050083 for cmd in self.cmds:
Andrew Geissler82c905d2020-04-13 13:39:40 -050084 result = runCmd(cmd, ignore_status=True, env=env)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050085 self._write_dump(cmd.split()[0], result.output)
86
Patrick Williamsc124f4f2015-09-15 14:41:29 -050087class TargetDumper(BaseDumper):
88 """ Class to get dumps from target, it only works with QemuRunner """
89
Brad Bishop6e60e8b2018-02-01 10:27:11 -050090 def __init__(self, cmds, parent_dir, runner):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050091 super(TargetDumper, self).__init__(cmds, parent_dir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -050092 self.runner = runner
Patrick Williamsc124f4f2015-09-15 14:41:29 -050093
94 def dump_target(self, dump_dir=""):
95 if dump_dir:
96 self.dump_dir = dump_dir
97 for cmd in self.cmds:
98 # We can continue with the testing if serial commands fail
99 try:
100 (status, output) = self.runner.run_serial(cmd)
101 self._write_dump(cmd.split()[0], output)
102 except:
103 print("Tried to dump info from target but "
104 "serial console failed")
Andrew Geisslerc926e172021-05-07 16:11:35 -0500105 print("Failed CMD: %s" % (cmd))
106
107class MonitorDumper(BaseDumper):
108 """ Class to get dumps via the Qemu Monitor, it only works with QemuRunner """
109
110 def __init__(self, cmds, parent_dir, runner):
111 super(MonitorDumper, self).__init__(cmds, parent_dir)
112 self.runner = runner
113
114 def dump_monitor(self, dump_dir=""):
115 if self.runner is None:
116 return
117 if dump_dir:
118 self.dump_dir = dump_dir
119 for cmd in self.cmds:
120 try:
121 output = self.runner.run_monitor(cmd)
122 self._write_dump(cmd, output)
123 except:
124 print("Failed to dump QMP CMD: %s" % (cmd))