[Autotest] /server/cros py3 migration

BUG=chromium:990593
TEST=dummy_Pass, python3 py_compile, python py_compile, unittests

Change-Id: I510a54e18087bce69e3c0acc3e7489d160ee7dc8
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/2319151
Tested-by: Derek Beckett <[email protected]>
Commit-Queue: Derek Beckett <[email protected]>
Reviewed-by: Ruben Zakarian <[email protected]>
diff --git a/server/cros/ap_config.py b/server/cros/ap_config.py
index e0d32b0..b8c296b 100644
--- a/server/cros/ap_config.py
+++ b/server/cros/ap_config.py
@@ -1,9 +1,10 @@
+# Lint as: python2, python3
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 import collections
-import ConfigParser
+import six.moves.configparser
 import logging
 import os
 import time
@@ -27,7 +28,7 @@
     aps = []
     # chaos_ap_list.conf holds static conf of all APs in lab.
     for filename in ['chaos_ap_list.conf']:
-        ap_config = ConfigParser.RawConfigParser(
+        ap_config = six.moves.configparser.RawConfigParser(
                 {AP.CONF_RPM_MANAGED: 'False'})
         path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                             filename)
@@ -136,7 +137,7 @@
         """@return string bss for AP from config file"""
         try:
             bss = self.ap_config.get(self.bss, self.CONF_BSS)
-        except ConfigParser.NoOptionError as e:
+        except six.moves.configparser.NoOptionError as e:
             bss = 'N/A'
         return bss
 
@@ -145,7 +146,7 @@
         """@return string bss5 for AP from config file"""
         try:
             bss5 = self.ap_config.get(self.bss, self.CONF_BSS5)
-        except ConfigParser.NoOptionError as e:
+        except six.moves.configparser.NoOptionError as e:
             bss5 = 'N/A'
         return bss5
 
diff --git a/server/cros/ap_config_unittest.py b/server/cros/ap_config_unittest.py
index 3319efc..c0b460d 100644
--- a/server/cros/ap_config_unittest.py
+++ b/server/cros/ap_config_unittest.py
@@ -1,8 +1,9 @@
+# Lint as: python2, python3
 # Copyright 2019 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import ConfigParser
+import six.moves.configparser
 import io
 import unittest
 
@@ -38,7 +39,7 @@
 
 
 def _parse_config_from_string(conf):
-    parser = ConfigParser.RawConfigParser()
+    parser = six.moves.configparser.RawConfigParser()
     parser.readfp(io.BytesIO(conf))
     return parser
 
diff --git a/server/cros/autoupdater.py b/server/cros/autoupdater.py
index 5e03fa3..9514c20 100644
--- a/server/cros/autoupdater.py
+++ b/server/cros/autoupdater.py
@@ -1,3 +1,4 @@
+# Lint as: python2, python3
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -9,7 +10,7 @@
 import re
 import six
 import sys
-import urlparse
+import six.moves.urllib.parse
 
 from autotest_lib.client.bin import utils
 from autotest_lib.client.common_lib import error
@@ -171,7 +172,7 @@
     # http://.../update/.../0.14.755.0/au/0.14.754.0. In this case we want to
     # strip off the au section of the path before reading the version.
     return re.sub('/au/.*', '',
-                  urlparse.urlparse(update_url).path).split('/')[-1].strip()
+                  six.moves.urllib.parse.urlparse(update_url).path).split('/')[-1].strip()
 
 
 def url_to_image_name(update_url):
@@ -185,7 +186,7 @@
     @returns a string representing the image name in the update_url.
 
     """
-    return urlparse.urlparse(update_url).path[len('/update/'):]
+    return six.moves.urllib.parse.urlparse(update_url).path[len('/update/'):]
 
 
 def get_update_failure_reason(exception):
@@ -330,7 +331,7 @@
             return remote_script
         self.host.run('mkdir -p -m 1777 /usr/local/tmp')
         remote_tmp_script = '/usr/local/tmp/%s' % script_name
-        server_name = urlparse.urlparse(self.update_url)[1]
+        server_name = six.moves.urllib.parse.urlparse(self.update_url)[1]
         script_url = 'http://%s/static/%s' % (server_name, script_name)
         fetch_script = 'curl -Ss -o %s %s && head -1 %s' % (
             remote_tmp_script, script_url, remote_tmp_script)
@@ -440,7 +441,7 @@
         """
         logging.info('Installing image at %s onto %s',
                      self.update_url, self.host.hostname)
-        server_name = urlparse.urlparse(self.update_url)[1]
+        server_name = six.moves.urllib.parse.urlparse(self.update_url)[1]
         image_name = url_to_image_name(self.update_url)
 
         logging.info('Installing image using quick-provision.')
diff --git a/server/cros/camerabox_utils.py b/server/cros/camerabox_utils.py
index 0f222f8..b3c7f8c 100644
--- a/server/cros/camerabox_utils.py
+++ b/server/cros/camerabox_utils.py
@@ -1,3 +1,4 @@
+# Lint as: python2, python3
 # Copyright 2018 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -7,7 +8,7 @@
 import logging
 from lxml import etree
 import os
-import StringIO
+import six
 import time
 
 from autotest_lib.client.common_lib import error, utils
@@ -111,7 +112,7 @@
             renumbered from 0.
         """
         tree = etree.parse(
-                StringIO.StringIO(content),
+                six.StringIO(content),
                 parser=etree.XMLParser(compact=False))
         root = tree.getroot()
         profiles = root.findall('CamcorderProfiles')
diff --git a/server/cros/cfm_jmidata_v3_helper.py b/server/cros/cfm_jmidata_v3_helper.py
index 3c38d4e..748d20e 100644
--- a/server/cros/cfm_jmidata_v3_helper.py
+++ b/server/cros/cfm_jmidata_v3_helper.py
@@ -1,10 +1,16 @@
+# Lint as: python2, python3
 # Copyright (c) 2017 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+
 import json
 
 from autotest_lib.server.cros import cfm_jmidata_helper_base
+from six.moves import range
 
 # Start index in the JSON object that contains Audio/Video streams related info.
 AV_INDEX = 4
diff --git a/server/cros/factory_install_test.py b/server/cros/factory_install_test.py
index 52db3e4..2e6b967 100644
--- a/server/cros/factory_install_test.py
+++ b/server/cros/factory_install_test.py
@@ -1,3 +1,4 @@
+# Lint as: python2, python3
 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -19,9 +20,9 @@
         only)
 """
 
-import glob, logging, os, re, shutil, socket, sys, thread, time, traceback
+import glob, logging, os, re, shutil, socket, sys, six.moves._thread, time, traceback
 from abc import abstractmethod
-from StringIO import StringIO
+from six import StringIO
 
 from autotest_lib.client.bin import utils as client_utils
 from autotest_lib.client.common_lib import error
@@ -226,7 +227,7 @@
             stdout_tee=utils.TEE_TO_LOGS,
             stderr_tee=open(self.miniomaha_output, "w"))
         self.cleanup_tasks.append(lambda: utils.nuke_subprocess(bg_job.sp))
-        thread.start_new_thread(utils.join_bg_jobs, ([bg_job],))
+        six.moves._thread.start_new_thread(utils.join_bg_jobs, ([bg_job],))
 
         client_utils.poll_for_condition(is_miniomaha_up,
                                         timeout=_MINIOMAHA_TIMEOUT_SEC,
diff --git a/server/cros/goofy_client.py b/server/cros/goofy_client.py
index c183960..57117cc 100644
--- a/server/cros/goofy_client.py
+++ b/server/cros/goofy_client.py
@@ -1,9 +1,10 @@
+# Lint as: python2, python3
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 import collections
-import httplib
+import six.moves.http_client
 import logging
 import os
 import re
@@ -150,7 +151,7 @@
                 GOOFY_JSONRPC_SERVER_PORT)
 
 
-    @retry.retry((httplib.BadStatusLine, socket.error),
+    @retry.retry((six.moves.http_client.BadStatusLine, socket.error),
                  timeout_min=BASE_RPC_TIMEOUT)
     def _raw_stop_running_tests(self):
         """Stop running tests by shelling out to the DUT.
@@ -168,7 +169,7 @@
         self._host.run('factory clear')
 
 
-    @retry_goofy_rpc((httplib.BadStatusLine, socket.error),
+    @retry_goofy_rpc((six.moves.http_client.BadStatusLine, socket.error),
                      timeout_min=BASE_RPC_TIMEOUT)
     def _get_goofy_status(self):
         """Return status of goofy, ignoring socket timeouts and http exceptions.
@@ -229,11 +230,11 @@
             # In partial automation mode manual tests and barrier are enabled
             # and user intervention is required; none disables automation.
             self._client.SwitchTestList(next_list, 'full')
-        except httplib.BadStatusLine:
+        except six.moves.http_client.BadStatusLine:
             logging.info('Switched to list %s, goofy restarting', next_list)
 
 
-    @retry_goofy_rpc((httplib.BadStatusLine, socket.error),
+    @retry_goofy_rpc((six.moves.http_client.BadStatusLine, socket.error),
                      timeout_min=BASE_RPC_TIMEOUT*2)
     def _stop_running_tests(self):
         """Stop all running tests.
@@ -277,7 +278,7 @@
             logging.error('Could not gather results for current test: %s', e)
 
 
-    @retry_goofy_rpc((httplib.BadStatusLine, socket.error),
+    @retry_goofy_rpc((six.moves.http_client.BadStatusLine, socket.error),
                      timeout_min=BASE_RPC_TIMEOUT*2)
     def _get_test_info(self, test_name):
         """Get the status of one test.
@@ -293,7 +294,7 @@
                           test_name)
 
 
-    @retry_goofy_rpc((httplib.BadStatusLine, socket.error),
+    @retry_goofy_rpc((six.moves.http_client.BadStatusLine, socket.error),
                      timeout_min=BASE_RPC_TIMEOUT*2)
     def _get_test_run_info(self, run_id):
         """Get the information about the given test run.
@@ -391,7 +392,7 @@
                                        current_suite)
 
 
-    @retry_goofy_rpc((httplib.BadStatusLine, socket.error),
+    @retry_goofy_rpc((six.moves.http_client.BadStatusLine, socket.error),
                      timeout_min=BASE_RPC_TIMEOUT*2)
     def get_results(self, resultsdir):
         """Copies results from the DUT to a local results directory.
diff --git a/server/cros/gsutil_wrapper.py b/server/cros/gsutil_wrapper.py
index cf55c4a..839f578 100644
--- a/server/cros/gsutil_wrapper.py
+++ b/server/cros/gsutil_wrapper.py
@@ -1,8 +1,12 @@
+# Lint as: python2, python3
 # Copyright 2015 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
 import logging
 import os.path
 import subprocess
@@ -42,8 +46,8 @@
 
         output = p.communicate()
 
-        log("STDOUT | " + output[0])
-        log("STDERR | " + output[1])
+        log("STDOUT | " + output[0].decode('utf-8'))
+        log("STDERR | " + output[1].decode('utf-8'))
 
         if p.returncode:
             raise subprocess.CalledProcessError(returncode=p.returncode,
diff --git a/server/cros/lockfile.py b/server/cros/lockfile.py
index 52063a1..44476fd 100644
--- a/server/cros/lockfile.py
+++ b/server/cros/lockfile.py
@@ -1,3 +1,4 @@
+# Lint as: python2, python3
 
 """
 lockfile.py - Platform-independent advisory file locks.
@@ -47,14 +48,17 @@
             NotMyLock - File was locked but not by the current thread/process
 """
 
+from __future__ import absolute_import
 from __future__ import division
+from __future__ import print_function
 
 import logging
 import socket
 import os
 import threading
 import time
-import urllib
+import six
+from six.moves import urllib
 
 # Work with PEP8 and non-PEP8 versions of threading module.
 if not hasattr(threading, "current_thread"):
@@ -139,7 +143,7 @@
         self.hostname = socket.gethostname()
         self.pid = os.getpid()
         name = threading.current_thread().get_name()
-        tname = "%s-" % urllib.quote(name, safe="")
+        tname = "%s-" % urllib.parse.quote(name, safe="")
         dirname = os.path.dirname(self.lock_file)
         self.unique_name = os.path.join(dirname, "%s.%s%s" % (self.hostname,
                                                               tname, self.pid))
diff --git a/server/cros/provision.py b/server/cros/provision.py
index 46d0b1f..4e9d493 100644
--- a/server/cros/provision.py
+++ b/server/cros/provision.py
@@ -1,3 +1,4 @@
+# Lint as: python2, python3
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -251,7 +252,7 @@
         if name in cls._priorities:
             return cls._priorities.index(name)
         else:
-            return sys.maxint
+            return sys.maxsize
 
 
 class Verify(_SpecialTaskAction):
diff --git a/server/cros/queue_barrier.py b/server/cros/queue_barrier.py
index c4a45ae..7a91638 100644
--- a/server/cros/queue_barrier.py
+++ b/server/cros/queue_barrier.py
@@ -1,8 +1,13 @@
+# Lint as: python2, python3
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
 from multiprocessing import Queue, queues
+from six.moves import range
 
 
 class QueueBarrierTimeout(Exception):
diff --git a/server/cros/resource_monitor.py b/server/cros/resource_monitor.py
index 9cdbd04..c8ec5f5 100644
--- a/server/cros/resource_monitor.py
+++ b/server/cros/resource_monitor.py
@@ -1,10 +1,15 @@
+# Lint as: python2, python3
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+
 import logging
 import csv
-import cStringIO
+import six
 import random
 import re
 import collections
@@ -153,7 +158,7 @@
 
 
     def __repr__(self):
-        output_stringfile = cStringIO.StringIO()
+        output_stringfile = six.StringIO()
         self.save_to_file(output_stringfile)
         return output_stringfile.getvalue()
 
diff --git a/server/cros/resource_monitor_unittest.py b/server/cros/resource_monitor_unittest.py
index d5065a6..df03968 100644
--- a/server/cros/resource_monitor_unittest.py
+++ b/server/cros/resource_monitor_unittest.py
@@ -1,7 +1,10 @@
+# Lint as: python2, python3
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+from __future__ import absolute_import
+from __future__ import division
 from __future__ import print_function
 
 import logging
@@ -11,10 +14,13 @@
 import common
 import os
 
-from itertools import imap
+
 from autotest_lib.server.cros import resource_monitor
 from autotest_lib.server.hosts import abstract_ssh
 from autotest_lib.server import utils
+import six
+from six.moves import map
+from six.moves import range
 
 class HostMock(abstract_ssh.AbstractSSHHost):
     """Mocks a host object."""
@@ -260,11 +266,11 @@
                 testdata_file)
         with open(testans_file, "rb") as testans:
             csvreader = csv.reader(testans)
-            columns = csvreader.next()
+            columns = next(csvreader)
             self.assertEqual(list(columns),
                     resource_monitor.ResourceMonitorParsedResult._columns)
             utils_over_time = []
-            for util_val in imap(
+            for util_val in map(
                     resource_monitor.
                             ResourceMonitorParsedResult.UtilValues._make,
                     csvreader):
diff --git a/server/cros/stress.py b/server/cros/stress.py
index f42fa13..9d09527 100755
--- a/server/cros/stress.py
+++ b/server/cros/stress.py
@@ -1,12 +1,18 @@
+# Lint as: python2, python3
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
 import logging
 import sys
 import threading
 import time
 from autotest_lib.client.common_lib import error
+import six
+from six.moves import range
 
 
 class BaseStressor(threading.Thread):
@@ -107,7 +113,7 @@
         if self._exc_info:
             exc_info = self._exc_info
             self._exc_info = None
-            raise exc_info[0], exc_info[1], exc_info[2]
+            six.reraise(exc_info[0], exc_info[1], exc_info[2])
 
 
 class ControlledStressor(BaseStressor):
@@ -177,7 +183,7 @@
     """
     def _loop_stressor(self):
         """Overloaded from parent."""
-        for iteration_num in xrange(1, self._iterations + 1):
+        for iteration_num in range(1, self._iterations + 1):
             logging.info('Stressor iteration: %d of %d',
                          iteration_num, self._iterations)
             self.stressor()
diff --git a/server/cros/telemetry_runner.py b/server/cros/telemetry_runner.py
index bd170f1..c795ba8 100644
--- a/server/cros/telemetry_runner.py
+++ b/server/cros/telemetry_runner.py
@@ -1,13 +1,18 @@
+# Lint as: python2, python3
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+
 import json
 import logging
 import numbers
 import os
 import tempfile
-import StringIO
+import six
 
 import numpy
 
@@ -296,8 +301,8 @@
         """
         logging.debug('Running: %s', cmd)
 
-        output = StringIO.StringIO()
-        error_output = StringIO.StringIO()
+        output = six.StringIO()
+        error_output = six.StringIO()
         exit_code = 0
         try:
             result = utils.run(
@@ -574,14 +579,14 @@
                 continue
             metric_name = obj['name']
             diagnostics = obj['diagnostics']
-            if diagnostics.has_key('stories'):
+            if 'stories' in diagnostics:
                 story_name = value_map[diagnostics['stories']][0]
             else:
                 story_name = 'default'
             local_benchmark_name = value_map[diagnostics['benchmarks']][0]
             if benchmark_name == '':
                 benchmark_name = local_benchmark_name
-                if diagnostics.has_key('benchmarkDescriptions'):
+                if 'benchmarkDescriptions' in diagnostics:
                     benchmark_desc = value_map[
                             diagnostics['benchmarkDescriptions']][0]
             if benchmark_name != local_benchmark_name:
diff --git a/server/cros/usb_mux_controller.py b/server/cros/usb_mux_controller.py
index 621e9ea..64198f1 100644
--- a/server/cros/usb_mux_controller.py
+++ b/server/cros/usb_mux_controller.py
@@ -1,8 +1,13 @@
+# Lint as: python2, python3
 # Copyriht (c) 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
 import logging
+import six
 
 # Following Beaglebone GPIO pins are used to control the 8 port multiplexer.
 MUX_EN = '20'