autotest: network_WiFi_AttenuatorPerf - Fix multiple issues

Fixing 3 issues that we have see on the attenuated (grover) setups in
the lab.
1) Unhandled timeout when opening telnet connection (crbug.com/854377)
2) TypeError for signal level. output_perf_value expects string or
number but wifi_signal_level returns None if signal is not detected.
This usually happens on runs with high attenuation (crbug.com/854378)
3) Telnet commands fails to return valid data. We use to see this error
sometimes prior to Aug 10 but since then failures resulting from this
has spiked. The issue seems to be with telnet connection that we create
though the connection remains open, we stop receiving expected data
using telnet expect. This seems to get worse with large number of
telnet calls. Closing and reopening telnet connection fixes the issue.
(crbug.com/876945)

BUG=chromium:854377, chromium:854378, chromium:876945
TEST=Tested against eve in grover setup in wifi lab.

Change-Id: Iccb711c59f29a216ea6a936c7757b4048fd0cc1c
Reviewed-on: https://chromium-review.googlesource.com/1188984
Commit-Ready: Harpreet Grewal <harpreet@chromium.org>
Tested-by: Harpreet Grewal <harpreet@chromium.org>
Reviewed-by: Kirtika Ruchandani <kirtika@chromium.org>
diff --git a/server/cros/network/attenuator.py b/server/cros/network/attenuator.py
index 2c194ec..70c3aae 100644
--- a/server/cros/network/attenuator.py
+++ b/server/cros/network/attenuator.py
@@ -49,6 +49,11 @@
         """Returns true if telnet connection to attenuator is open."""
         return bool(self._tnhelper.is_open())
 
+    def reopen(self, host, port=22):
+        """Close and reopen telnet connection to the attenuator."""
+        self._tnhelper.close()
+        self._tnhelper.open(host, port)
+
     def close(self):
         """Closes the telnet connection."""
         self._tnhelper.close()
diff --git a/server/cros/network/attenuator_controller.py b/server/cros/network/attenuator_controller.py
index 1d5e4d4..af96b2d 100644
--- a/server/cros/network/attenuator_controller.py
+++ b/server/cros/network/attenuator_controller.py
@@ -98,6 +98,7 @@
         @param hostname: Hostname representing minicircuits attenuator.
 
         """
+        self.hostname = hostname
         super(AttenuatorController, self).__init__()
         if hostname not in HOST_TO_FIXED_ATTENUATIONS.keys():
             raise error.TestError('Unexpected RvR host name %r.' % hostname)
@@ -172,15 +173,21 @@
                 set all variable attenuators.
 
         """
-
         affected_attenuators = self.supported_attenuators
         if attenuator_num is not None:
             affected_attenuators = [attenuator_num]
         for atten in affected_attenuators:
-            self._attenuator.set_atten(atten, atten_db)
-            if int(self._attenuator.get_atten(atten)) != atten_db:
-                raise error.TestError('Attenuation did not set as expected on '
-                                      'attenuator %d' % atten)
+            try:
+                self._attenuator.set_atten(atten, atten_db)
+                if int(self._attenuator.get_atten(atten)) != atten_db:
+                    raise error.TestError('Attenuation did not set as expected '
+                                          'on attenuator %d' % atten)
+            except error.TestError:
+                self._attenuator.reopen(self.hostname)
+                self._attenuator.set_atten(atten, atten_db)
+                if int(self._attenuator.get_atten(atten)) != atten_db:
+                    raise error.TestError('Attenuation did not set as expected '
+                                          'on attenuator %d' % atten)
             logging.info('%ddb attenuation set successfully on attenautor %d',
                          atten_db, atten)
 
diff --git a/server/cros/network/telnet_helper.py b/server/cros/network/telnet_helper.py
index 13fdce8..cef88e3 100644
--- a/server/cros/network/telnet_helper.py
+++ b/server/cros/network/telnet_helper.py
@@ -8,7 +8,7 @@
 from autotest_lib.client.common_lib import error
 
 SHORT_TIMEOUT = 2
-LONG_TIMEOUT = 10
+LONG_TIMEOUT = 30
 
 class TelnetHelper(object):
     """Helper class to run basic string commands on a telnet host."""
@@ -31,7 +31,11 @@
             self._tn.close()
 
         self._tn = telnetlib.Telnet()
-        self._tn.open(hostname, port, LONG_TIMEOUT)
+
+        try:
+            self._tn.open(hostname, port, LONG_TIMEOUT)
+        except socket.timeout as e:
+            raise error.TestError("Timed out while opening telnet connection")
 
     def is_open(self):
         """Returns true if telnet connection is open."""
diff --git a/server/site_tests/network_WiFi_AttenuatedPerf/network_WiFi_AttenuatedPerf.py b/server/site_tests/network_WiFi_AttenuatedPerf/network_WiFi_AttenuatedPerf.py
index 2df1ba3..34e14db 100644
--- a/server/site_tests/network_WiFi_AttenuatedPerf/network_WiFi_AttenuatedPerf.py
+++ b/server/site_tests/network_WiFi_AttenuatedPerf/network_WiFi_AttenuatedPerf.py
@@ -61,6 +61,7 @@
 
 
     def run_once(self):
+        """Run test."""
         start_time = time.time()
         throughput_data = []
         max_atten = None
@@ -100,20 +101,23 @@
             for config in self.NETPERF_CONFIGS:
                 results = session.run(config)
                 if not results:
-                    logging.warning('Unable to take measurement for %s; aborting',
-                                    config.human_readable_tag)
+                    logging.warning('Unable to take measurement for %s; '
+                                    'aborting', config.human_readable_tag)
                     break
                 graph_name = '.'.join(
                         [self._ap_config.perf_loggable_description, config.tag])
                 values = [result.throughput for result in results]
+                # If no signal is detected with client.wifi_signal_level, set
+                # signal_level to -100 to indicate weak signal.
+                signal_level = (self.context.client.wifi_signal_level if
+                        self.context.client.wifi_signal_level else -100)
                 self.output_perf_value(atten_tag, values, units='Mbps',
                                        higher_is_better=True, graph=graph_name)
                 self.output_perf_value('_'.join([atten_tag, 'signal']),
-                                       self.context.client.wifi_signal_level,
+                                       signal_level,
                                        units='dBm', higher_is_better=True,
                                        graph=graph_name)
                 result = netperf_runner.NetperfResult.from_samples(results)
-                signal_level = self.context.client.wifi_signal_level
                 throughput_data.append(self.DataPoint(
                         atten,
                         result.throughput,