<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-gsm-tester/+/17810">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">iperf3: Avoid using --logfile arg<br><br>Some older iperf3 versions don't support the --logfile arg. Let's<br>instead parse the json from stdout. Old --logfile behavior is left in<br>code but disabled since it's a nicer (less hacky) way to get results,<br>because parsing from stdout means we need to avoid reading some content.<br><br>Change-Id: Ia1b7fa4dae074089878963aeddf0006aea68e31f<br>---<br>M src/osmo_gsm_tester/obj/iperf3.py<br>1 file changed, 44 insertions(+), 23 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/10/17810/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/osmo_gsm_tester/obj/iperf3.py b/src/osmo_gsm_tester/obj/iperf3.py</span><br><span>index d2e9c36..9427770 100644</span><br><span>--- a/src/osmo_gsm_tester/obj/iperf3.py</span><br><span>+++ b/src/osmo_gsm_tester/obj/iperf3.py</span><br><span>@@ -23,14 +23,20 @@</span><br><span> from ..core import log, util, config, process, remote</span><br><span> from . import pcap_recorder, run_node</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-def iperf3_result_to_json(file):</span><br><span style="color: hsl(0, 100%, 40%);">- with open(file) as f:</span><br><span style="color: hsl(0, 100%, 40%);">- # Sometimes iperf3 provides 2 dictionaries, the 2nd one being an error about being interrupted (by us).</span><br><span style="color: hsl(0, 100%, 40%);">- # json parser doesn't support (raises exception) parsing several dictionaries at a time (not a valid json object).</span><br><span style="color: hsl(0, 100%, 40%);">- # We are only interested in the first dictionary, the regular results one:</span><br><span style="color: hsl(0, 100%, 40%);">- d = f.read().split("\n}\n")[0] + "\n}\n"</span><br><span style="color: hsl(0, 100%, 40%);">- data = json.loads(d)</span><br><span style="color: hsl(0, 100%, 40%);">- return data</span><br><span style="color: hsl(120, 100%, 40%);">+def iperf3_result_to_json(log_obj, data):</span><br><span style="color: hsl(120, 100%, 40%);">+ try:</span><br><span style="color: hsl(120, 100%, 40%);">+ # Drop non-interesting self-generated output before json:</span><br><span style="color: hsl(120, 100%, 40%);">+ if not data.startswith('{\n'):</span><br><span style="color: hsl(120, 100%, 40%);">+ data = "{\n" + data.split("\n{\n")[1]</span><br><span style="color: hsl(120, 100%, 40%);">+ # Sometimes iperf3 provides 2 dictionaries, the 2nd one being an error about being interrupted (by us).</span><br><span style="color: hsl(120, 100%, 40%);">+ # json parser doesn't support (raises exception) parsing several dictionaries at a time (not a valid json object).</span><br><span style="color: hsl(120, 100%, 40%);">+ # We are only interested in the first dictionary, the regular results one:</span><br><span style="color: hsl(120, 100%, 40%);">+ data = data.split("\n}")[0] + "\n}"</span><br><span style="color: hsl(120, 100%, 40%);">+ j = json.loads(data)</span><br><span style="color: hsl(120, 100%, 40%);">+ return j</span><br><span style="color: hsl(120, 100%, 40%);">+ except Exception as e:</span><br><span style="color: hsl(120, 100%, 40%);">+ log_obj.log('failed parsing iperf3 output: "%s"' % data)</span><br><span style="color: hsl(120, 100%, 40%);">+ raise e</span><br><span> </span><br><span> </span><br><span> class IPerf3Server(log.Origin):</span><br><span>@@ -51,11 +57,12 @@</span><br><span> self.rem_host = None</span><br><span> self.remote_log_file = None</span><br><span> self.log_copied = False</span><br><span style="color: hsl(120, 100%, 40%);">+ self.logfile_supported = False # some older versions of iperf doesn't support --logfile arg</span><br><span> </span><br><span> def cleanup(self):</span><br><span> if self.process is None:</span><br><span> return</span><br><span style="color: hsl(0, 100%, 40%);">- if self.runs_locally():</span><br><span style="color: hsl(120, 100%, 40%);">+ if self.runs_locally() or not self.logfile_supported:</span><br><span> return</span><br><span> # copy back files (may not exist, for instance if there was an early error of process):</span><br><span> try:</span><br><span>@@ -86,8 +93,10 @@</span><br><span> self.rem_host.recreate_remote_dir(remote_run_dir)</span><br><span> </span><br><span> args = ('iperf3', '-s', '-B', self.addr(),</span><br><span style="color: hsl(0, 100%, 40%);">- '-p', str(self._port), '-J',</span><br><span style="color: hsl(0, 100%, 40%);">- '--logfile', self.remote_log_file)</span><br><span style="color: hsl(120, 100%, 40%);">+ '-p', str(self._port), '-J')</span><br><span style="color: hsl(120, 100%, 40%);">+ if self.logfile_supported:</span><br><span style="color: hsl(120, 100%, 40%);">+ args += ('--logfile', self.remote_log_file,)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> self.process = self.rem_host.RemoteProcess(self.name(), args)</span><br><span> self.suite_run.remember_to_stop(self.process)</span><br><span> self.process.launch()</span><br><span>@@ -97,8 +106,9 @@</span><br><span> 'host %s and port not 22' % self.addr())</span><br><span> </span><br><span> args = ('iperf3', '-s', '-B', self.addr(),</span><br><span style="color: hsl(0, 100%, 40%);">- '-p', str(self._port), '-J',</span><br><span style="color: hsl(0, 100%, 40%);">- '--logfile', os.path.abspath(self.log_file))</span><br><span style="color: hsl(120, 100%, 40%);">+ '-p', str(self._port), '-J')</span><br><span style="color: hsl(120, 100%, 40%);">+ if self.logfile_supported:</span><br><span style="color: hsl(120, 100%, 40%);">+ args += ('--logfile', os.path.abspath(self.log_file),)</span><br><span> </span><br><span> self.process = process.Process(self.name(), self.run_dir, args, env={})</span><br><span> self.suite_run.remember_to_stop(self.process)</span><br><span>@@ -114,10 +124,14 @@</span><br><span> self.suite_run.stop_process(self.process)</span><br><span> </span><br><span> def get_results(self):</span><br><span style="color: hsl(0, 100%, 40%);">- if not self.runs_locally() and not self.log_copied:</span><br><span style="color: hsl(0, 100%, 40%);">- self.rem_host.scpfrom('scp-back-log', self.remote_log_file, self.log_file)</span><br><span style="color: hsl(0, 100%, 40%);">- self.log_copied = True</span><br><span style="color: hsl(0, 100%, 40%);">- return iperf3_result_to_json(self.log_file)</span><br><span style="color: hsl(120, 100%, 40%);">+ if self.logfile_supported:</span><br><span style="color: hsl(120, 100%, 40%);">+ if not self.runs_locally() and not self.log_copied:</span><br><span style="color: hsl(120, 100%, 40%);">+ self.rem_host.scpfrom('scp-back-log', self.remote_log_file, self.log_file)</span><br><span style="color: hsl(120, 100%, 40%);">+ self.log_copied = True</span><br><span style="color: hsl(120, 100%, 40%);">+ with open(self.log_file) as f:</span><br><span style="color: hsl(120, 100%, 40%);">+ return iperf3_result_to_json(self, f.read())</span><br><span style="color: hsl(120, 100%, 40%);">+ else:</span><br><span style="color: hsl(120, 100%, 40%);">+ return iperf3_result_to_json(self, self.process.get_stdout())</span><br><span> </span><br><span> def addr(self):</span><br><span> return self.ip_address.get('addr')</span><br><span>@@ -150,6 +164,7 @@</span><br><span> self.rem_host = None</span><br><span> self.remote_log_file = None</span><br><span> self.log_copied = False</span><br><span style="color: hsl(120, 100%, 40%);">+ self.logfile_supported = False # some older versions of iperf doesn't support --logfile arg</span><br><span> </span><br><span> def runs_locally(self):</span><br><span> locally = not self._run_node or self._run_node.is_local()</span><br><span>@@ -191,8 +206,9 @@</span><br><span> </span><br><span> popen_args = ('iperf3', '-c', self.server.addr(),</span><br><span> '-p', str(self.server.port()), '-J',</span><br><span style="color: hsl(0, 100%, 40%);">- '--logfile', self.remote_log_file,</span><br><span> '-t', str(time_sec))</span><br><span style="color: hsl(120, 100%, 40%);">+ if self.logfile_supported:</span><br><span style="color: hsl(120, 100%, 40%);">+ popen_args += ('--logfile', self.remote_log_file,)</span><br><span> if downlink:</span><br><span> popen_args += ('-R',)</span><br><span> </span><br><span>@@ -208,8 +224,9 @@</span><br><span> </span><br><span> popen_args = ('iperf3', '-c', self.server.addr(),</span><br><span> '-p', str(self.server.port()), '-J',</span><br><span style="color: hsl(0, 100%, 40%);">- '--logfile', os.path.abspath(self.log_file),</span><br><span> '-t', str(time_sec))</span><br><span style="color: hsl(120, 100%, 40%);">+ if self.logfile_supported:</span><br><span style="color: hsl(120, 100%, 40%);">+ popen_args += ('--logfile', os.path.abspath(self.log_file),)</span><br><span> if downlink:</span><br><span> popen_args += ('-R',)</span><br><span> </span><br><span>@@ -225,10 +242,14 @@</span><br><span> return self.get_results()</span><br><span> </span><br><span> def get_results(self):</span><br><span style="color: hsl(0, 100%, 40%);">- if not self.runs_locally() and not self.log_copied:</span><br><span style="color: hsl(0, 100%, 40%);">- self.rem_host.scpfrom('scp-back-log', self.remote_log_file, self.log_file)</span><br><span style="color: hsl(0, 100%, 40%);">- self.log_copied = True</span><br><span style="color: hsl(0, 100%, 40%);">- return iperf3_result_to_json(self.log_file)</span><br><span style="color: hsl(120, 100%, 40%);">+ if self.logfile_supported:</span><br><span style="color: hsl(120, 100%, 40%);">+ if not self.runs_locally() and not self.log_copied:</span><br><span style="color: hsl(120, 100%, 40%);">+ self.rem_host.scpfrom('scp-back-log', self.remote_log_file, self.log_file)</span><br><span style="color: hsl(120, 100%, 40%);">+ self.log_copied = True</span><br><span style="color: hsl(120, 100%, 40%);">+ with open(self.log_file) as f:</span><br><span style="color: hsl(120, 100%, 40%);">+ return iperf3_result_to_json(self, f.read())</span><br><span style="color: hsl(120, 100%, 40%);">+ else:</span><br><span style="color: hsl(120, 100%, 40%);">+ return iperf3_result_to_json(self, self.process.get_stdout())</span><br><span> </span><br><span> def set_run_node(self, run_node):</span><br><span> self._run_node = run_node</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-gsm-tester/+/17810">change 17810</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-gsm-tester/+/17810"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-gsm-tester </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ia1b7fa4dae074089878963aeddf0006aea68e31f </div>
<div style="display:none"> Gerrit-Change-Number: 17810 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>