[autotest] network/frame_sender: grab send_management_frame logs

We run send_management_frame as a sort of background process, tracked by
PID. Grab its redirected stdout/stderr after we kill it.

We have to wait for the process to actually die, otherwise we might miss
some of its std{out,err}. I open-coded the simple shell loop, since
utils.poll_for_condition() would require a new host.run() (SSH)
invocation for each 'kill', which would be needlessly slow.

BUG=chromium:511318
TEST=run network_WiFi_ChannelScanDwellTime (also, with modifications to
     run multiple FrameSender), look for debug/frame_sender_*.log

Change-Id: I8694eecd3cf662b1d0f0f439981bdd9d16c0e083
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/1495931
Reviewed-by: Yen-lin Lai <yenlinlai@google.com>
Commit-Queue: Brian Norris <briannorris@chromium.org>
Tested-by: Brian Norris <briannorris@chromium.org>
diff --git a/server/cros/network/frame_sender.py b/server/cros/network/frame_sender.py
index 98968e0..eabd4e2 100644
--- a/server/cros/network/frame_sender.py
+++ b/server/cros/network/frame_sender.py
@@ -3,10 +3,12 @@
 # found in the LICENSE file.
 
 from autotest_lib.client.common_lib import error
+import os
 
 class FrameSender(object):
     """Context manager for sending management frames."""
 
+    _sender_count = 0
 
     def __init__(self, router, frame_type, channel, ssid_prefix=None,
                  num_bss=None, frame_count=None, delay=None, dest_addr=None,
@@ -40,6 +42,9 @@
         self._injection_interface = None
         self._pid = None
 
+        self._index = FrameSender._sender_count
+        FrameSender._sender_count += 1
+
 
     def __enter__(self):
         self._injection_interface = self._router.get_configured_interface(
@@ -57,4 +62,13 @@
         if self._injection_interface:
             self._router.release_interface(self._injection_interface)
         if self._pid:
-            self._router.host.run('kill %d' % self._pid, ignore_status=True)
+            # Kill process and wait for termination.
+            self._router.host.run(
+                'kill {pid};'
+                ' for i in $(seq 1 10); do'
+                ' kill -0 {pid} || break; sleep 0.2;'
+                ' done'.format(pid=self._pid), ignore_status=True)
+            self._router.host.get_file(
+                os.path.join(
+                    self._router.logdir, self._router.MGMT_FRAME_SENDER_LOG_FILE),
+                'debug/frame_sender_%d.log' % self._index)