Closed patrislav1 closed 3 years ago
Hi,
would be nice to have some tests with your specific output
I would suggest to move the parsing stuff to a function like:
--- a/pyipmi/interfaces/ipmitool.py
+++ b/pyipmi/interfaces/ipmitool.py
@@ -90,6 +90,13 @@ class Ipmitool(object):
return accessible
+ def _parse_output(self, output):
+ # check for errors
+ completion_code = self.re_completion_code.match(output)
+ timeout = self.re_timeout.match(output)
+
+ return (completion_code, timeout)
+
def send_and_receive_raw(self, target, lun, netfn, raw_bytes):
if self._interface_type in ['lan', 'lanplus']:
@@ -104,15 +111,13 @@ class Ipmitool(object):
self._interface_type)
output, rc = self._run_ipmitool(cmd)
+ (completion_code, timeout) = self._parse_output(output)
- # check for errors
- match_completion_code = self.re_completion_code.match(output)
- match_timeout = self.re_timeout.match(output)
data = array('B')
- if match_completion_code:
- cc = int(match_completion_code.group(1), 16)
+ if completion_code:
+ cc = int(completion_code.group(1), 16)
data.append(cc)
- elif match_timeout:
+ elif timeout:
raise IpmiTimeoutError()
else:
if rc != 0:
and write some tests for that ... what do you think?
e some tests for that ... what do you think?
I would suggest to move the parsing stuff to a function like:
--- a/pyipmi/interfaces/ipmitool.py +++ b/pyipmi/interfaces/ipmitool.py @@ -90,6 +90,13 @@ class Ipmitool(object): return accessible + def _parse_output(self, output): + # check for errors + completion_code = self.re_completion_code.match(output) + timeout = self.re_timeout.match(output) + + return (completion_code, timeout) + def send_and_receive_raw(self, target, lun, netfn, raw_bytes): if self._interface_type in ['lan', 'lanplus']: @@ -104,15 +111,13 @@ class Ipmitool(object): self._interface_type) output, rc = self._run_ipmitool(cmd) + (completion_code, timeout) = self._parse_output(output) - # check for errors - match_completion_code = self.re_completion_code.match(output) - match_timeout = self.re_timeout.match(output) data = array('B') - if match_completion_code: - cc = int(match_completion_code.group(1), 16) + if completion_code: + cc = int(completion_code.group(1), 16) data.append(cc) - elif match_timeout: + elif timeout: raise IpmiTimeoutError() else: if rc != 0:
and write some tests for that ... what do you think?
this is not enough since the valid data output parsing also includes the return data ... so my suggestion should not be the final solution ;-/
I would suggest to move the parsing stuff to a function like:
Good point - all the parsing should be deferred to after ipmitool
's error messages have been thrown out.
Added separate parsing function and tests as suggested.
I got a use case where ipmitool doesn't fail, but prepends the raw data with a error message line, probably due to a MicroTCA MCH failing a capabilities request. The requested IPMI access as such does succeed and data is printed out. example:
pyipmi.interfaces.ipmitool.send_and_receive_raw()
tries to parse the error message as hex dump (see below)This patch throws out all error message lines (those that contain the word 'failed') to make sure ipmitool's hex output is still parsed.