Begin upgrading `sample` script.
This will ultimately let it run a remote sample script to collect data
on TV Boxes and a controlling laptop at the same time. But there's some
prep work to do before we get there.
Change-Id: I792bd5bd6987725276316b3b033e285d6f017d3e
diff --git a/wifitables/sample.py b/wifitables/sample.py
index 53a3c62..6ff88cf 100755
--- a/wifitables/sample.py
+++ b/wifitables/sample.py
@@ -25,19 +25,27 @@
m,monitor= wireless monitor interface to use [{1}]
"""
+DEVNULL = open(os.devnull, 'wb')
-def Iperf(host, udp=False, bandwidth=20, bind=None):
+
+def Ping(host):
+ code = subprocess.call(['ping', '-c', '1', host], stdout=DEVNULL,
+ stderr=DEVNULL)
+ return code
+
+
+def Iperf(host, path, udp=False, bandwidth=20, bind=None):
"""Run iperf against host and report results."""
line = ['iperf', '-c', host]
- prefix = 'iperf'
+ name = 'iperf'
if udp:
line += ['-u', '-b', str(bandwidth * 1000000)]
- prefix += 'u'
+ name += 'u'
if bind:
line += ['-B', bind]
- out = tempfile.NamedTemporaryFile(prefix=prefix)
+ out = open(os.path.join(path, name), 'w+')
subprocess.check_call(line, stdout=out)
return out
@@ -68,13 +76,13 @@
print >> out
-def MCS(bssid, interface):
+def MCS(bssid, interface, path):
"""Runs tcpdump in the background to gather wireless MCS."""
print 'Please enter password for `sudo` if prompted.'
subprocess.call(['sudo', '-v'])
- out = tempfile.NamedTemporaryFile(prefix='mcs')
- err = tempfile.NamedTemporaryFile(prefix='mcserr')
+ out = open(os.path.join(path, 'mcs'), 'w+')
+ err = open(os.path.join(path, 'mcserr'), 'w+')
filt = ('(not subtype beacon and not subtype ack) and '
'(wlan addr1 {0} or wlan addr2 {0} or wlan addr3 {0})'.format(
@@ -89,14 +97,14 @@
return sudo_tcpdump, out, err
-def IwLink(devname):
- out = tempfile.NamedTemporaryFile(prefix='iwlink')
+def IwLink(devname, path):
+ out = open(os.path.join(path, 'iwlink'), 'w+')
subprocess.check_call(['iw', 'dev', devname, 'link'], stdout=out)
return out
-def IwScan(devname):
- out = tempfile.NamedTemporaryFile(prefix='iwlink')
+def IwScan(devname, path):
+ out = open(os.path.join(path, 'iwscan'), 'w+')
subprocess.check_call(['iw', 'dev', devname, 'scan', 'dump'], stdout=out)
if os.fstat(out.file.fileno()).st_size: return out
@@ -104,22 +112,22 @@
return out
-def IpAddr():
- out = tempfile.NamedTemporaryFile(prefix='ipaddr')
+def IpAddr(path):
+ out = open(os.path.join(path, 'ipaddr'), 'w+')
subprocess.check_call(['ip', '-o', '-f', 'inet', 'addr'], stdout=out)
return out
-def AirportI():
+def AirportI(path):
"""Gather information about the current wireless network from `airport`."""
- out = tempfile.NamedTemporaryFile(prefix='airport')
+ out = open(os.path.join(path, 'airport'), 'w+')
subprocess.check_call(['airport', '-I'], stdout=out)
return out
-def AirportScan():
+def AirportScan(path):
"""Gather information about other observable networks from `airport`."""
- out = tempfile.NamedTemporaryFile(prefix='airportscan')
+ out = open(os.path.join(path, 'airportscan'), 'w+')
subprocess.check_call(['airport', '-s'], stdout=out)
return out
@@ -144,20 +152,25 @@
if extra:
o.fatal('did not understand supplied extra arguments.')
+ # Pick the report name before we run it, so it can be consistent across
+ # multiple systems.
+ report_name = 'wifi-{}-{:04}'.format(time.time(), opt.steps)
+ report_dir = tempfile.mkdtemp(prefix='wifi')
+
# we run diagnostics, write their output to files, and gather the files into
# a report that we present at the end of the run.
outputs = []
addr = ''
if system == 'Darwin':
- ai = AirportI()
+ ai = AirportI(report_dir)
ai.seek(0)
bssid = report.ParseAirportI(ai.read())['BSSID']
- outputs += [ai, AirportScan()]
+ outputs += [ai, AirportScan(report_dir)]
elif system == 'Linux':
# It's really likely we're running on a device with more than one interface.
# Be sure we're using the one that we're trying to test.
- ip = IpAddr()
+ ip = IpAddr(report_dir)
ip.seek(0)
addrmap = report.ParseIpAddr(ip.read())
addr = addrmap.get(opt.interface)
@@ -171,48 +184,51 @@
if mask > -1:
addr = addr[:mask]
- il = IwLink(opt.interface)
+ il = IwLink(opt.interface, report_dir)
il.seek(0)
bssid = report.ParseIwLink(il.read())['BSSID']
- ic = IwScan(opt.interface)
+ ic = IwScan(opt.interface, report_dir)
outputs += [ip, il, ic]
else:
raise OSError('This script requires Mac OS X or Linux.')
if opt.monitor:
- sudo_tcpdump, mcs_out, mcs_err = MCS(bssid, opt.monitor)
+ sudo_tcpdump, mcs_out, mcs_err = MCS(bssid, opt.monitor, report_dir)
print 'Gathering tcpdump in background as', sudo_tcpdump.pid
outputs += [mcs_out, mcs_err]
- it = Iperf(opt.destination, bind=addr)
+ status = Ping(opt.destination)
+ if not status:
+ it = Iperf(opt.destination, report_dir, bind=addr)
- # Empirically about 1.25x more packets make it through in UDP than TCP.
- # Try to saturate the channel by sending a bit more than that over UDP.
- it.seek(0)
- it_iperf = report.ParseIperfTCP(it.read())
+ # Empirically about 1.25x more packets make it through in UDP than TCP.
+ # Try to saturate the channel by sending a bit more than that over UDP.
+ it.seek(0)
+ it_iperf = report.ParseIperfTCP(it.read())
- bandwidth = it_iperf.get('bandwidth', 0.01)
- outputs += [it, Iperf(opt.destination, udp=True, bandwidth=bandwidth * 1.5,
- bind=addr)]
+ bandwidth = it_iperf.get('bandwidth', 0.01)
+ outputs += [it, Iperf(opt.destination, report_dir, udp=True,
+ bandwidth=bandwidth * 1.5,
+ bind=addr)]
+ else:
+ print >> sys.stderr, ('Could not ping destination host {0}; '
+ 'skipping performance tests').format(opt.destination)
if opt.monitor:
subprocess.check_call(['sudo', 'kill', str(sudo_tcpdump.pid)])
- report_name = 'wifi-{}-{:04}'.format(time.time(), opt.steps)
if opt.journal:
with open(opt.journal, 'a') as journal:
print >> journal, report_name
- report_dir = os.path.join(os.path.dirname(opt.journal), report_name)
+ dest_dir = os.path.join(os.path.dirname(opt.journal), report_name)
else:
- report_dir = report_name
+ dest_dir = report_name
- os.mkdir(report_dir)
- for page in outputs:
- shutil.copy(page.name,
- os.path.join(report_dir, os.path.basename(page.name[:-6])))
-
- print 'Report written to', report_dir
+ shutil.move(report_dir, dest_dir)
+ print 'Report written to', dest_dir
+ for name in (o.name for o in outputs):
+ print '*', os.path.basename(name)
if __name__ == '__main__':