[Autotest][PY3] Migrating site_utils (suite_preprocessor.py to end)

BUG=chromium:990593
TEST=dummy_pass, suite:dummy

Change-Id: I62c340cc8f0310f2fd4c486398167a4386fd851a
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/2565066
Reviewed-by: Greg Edelston <gredelston@google.com>
Commit-Queue: Derek Beckett <dbeckett@chromium.org>
Tested-by: Derek Beckett <dbeckett@chromium.org>
diff --git a/site_utils/suite_preprocessor.py b/site_utils/suite_preprocessor.py
index 99e78ca..3f0452d 100755
--- a/site_utils/suite_preprocessor.py
+++ b/site_utils/suite_preprocessor.py
@@ -8,6 +8,9 @@
 Deprecated tool for preprocessing tests to determine their DEPENDENCIES.
 """
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
 import optparse, os, sys
 import common
 
@@ -42,7 +45,7 @@
         with open(options.output_file, 'w') as file_obj:
             file_obj.write('%r' % test_deps)
     else:
-        print '%r' % test_deps
+        print('%r' % test_deps)
 
 
 if __name__ == "__main__":
diff --git a/site_utils/sync_cloudsql_access.py b/site_utils/sync_cloudsql_access.py
index 2254ae9..3abb94b 100755
--- a/site_utils/sync_cloudsql_access.py
+++ b/site_utils/sync_cloudsql_access.py
@@ -22,6 +22,10 @@
 
 """
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+
 import argparse
 import socket
 import sys
@@ -89,9 +93,9 @@
             'CLOUD', 'tko_access_servers', default='')
     if tko_servers:
         servers.extend(tko_servers.split(','))
-    print 'Adding servers %s to access list for projects %s' % (servers,
-                                                                instance)
-    print 'Fetching their IP addresses...'
+    print('Adding servers %s to access list for projects %s' % (servers,
+                                                                instance))
+    print('Fetching their IP addresses...')
     ips = []
     for name in servers:
         try:
@@ -100,18 +104,18 @@
             # collect external ips
             ips.append(_fetch_external_ip(name))
         except socket.gaierror:
-            print 'Failed to resolve internal IP address for name %s' % name
+            print('Failed to resolve internal IP address for name %s' % name)
             raise
         except error.TimeoutException:
-            print 'Failed to resolve external IP address for %s' % name
+            print('Failed to resolve external IP address for %s' % name)
             raise
 
-    print '...Done: %s' % ips
+    print('...Done: %s' % ips)
 
     cidr_ips = [str(ip) + '/32' for ip in ips]
 
     if dryrun:
-        print 'This is a dryrun: skip updating glcoud sql allowlists.'
+        print('This is a dryrun: skip updating glcoud sql allowlists.')
         return
 
     login = False
@@ -120,7 +124,7 @@
             utils.run('gcloud config set project %s -q' % project)
             cmd = ('gcloud sql instances patch %s --authorized-networks %s '
                    '-q' % (instance, ','.join(cidr_ips)))
-            print 'Running command to update allowlists: "%s"' % cmd
+            print('Running command to update allowlists: "%s"' % cmd)
             utils.run(cmd, stdout_tee=sys.stdout, stderr_tee=sys.stderr)
             return
         except error.CmdError:
diff --git a/site_utils/test_push.py b/site_utils/test_push.py
index f1f1fb6..e19f739 100755
--- a/site_utils/test_push.py
+++ b/site_utils/test_push.py
@@ -18,6 +18,10 @@
 
 """
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+
 import argparse
 import ast
 import datetime
@@ -29,7 +33,7 @@
 import sys
 import time
 import traceback
-import urllib2
+from six.moves import urllib
 
 import common
 try:
@@ -108,7 +112,7 @@
     @param pool: the pool used by test_push.
     @raise TestPushException: if number of DUTs are less than the requirement.
     """
-    print 'Checking DUT inventory...'
+    print('Checking DUT inventory...')
     pool_label = constants.Labels.POOL_PREFIX + pool
     hosts = AFE.run('get_hosts', status='Ready', locked=False)
     hosts = [h for h in hosts if pool_label in h.get('labels', [])]
@@ -154,7 +158,7 @@
 
 def reverify_all_push_duts():
     """Reverify all the push DUTs."""
-    print 'Reverifying all DUTs.'
+    print('Reverifying all DUTs.')
     hosts = [h.hostname for h in AFE.get_hosts()]
     AFE.reverify_hosts(hostnames=hosts)
 
@@ -270,7 +274,7 @@
         # Break when run_suite process completed.
         if not line and proc.poll() != None:
             break
-        print line.rstrip()
+        print(line.rstrip())
         _run_suite_output.append(line.rstrip())
 
         if not suite_job_id:
@@ -295,7 +299,7 @@
                         'flag has timed out after %d mins. Aborting it.' %
                         arguments.timeout_min)
 
-    print 'Suite job %s is completed.' % suite_job_id
+    print('Suite job %s is completed.' % suite_job_id)
     return suite_job_id
 
 
@@ -306,7 +310,7 @@
     @param suite_job_id: job ID of the suite job.
     @raise TestPushException: If a DUT does not have expected build imaged.
     """
-    print 'Checking image installed in DUTs...'
+    print('Checking image installed in DUTs...')
     job_ids = [job.id for job in
                models.Job.objects.filter(parent_job_id=suite_job_id)]
     hqes = [models.HostQueueEntry.objects.filter(job_id=job_id)[0]
@@ -352,7 +356,7 @@
     @param expected_results: A dictionary of test name to test result.
     @raise TestPushException: If verify fails.
     """
-    print 'Comparing test results...'
+    print('Comparing test results...')
     test_views = site_utils.get_test_views_from_tko(job_id, TKO)
     summary = test_push_common.summarize_push(test_views, expected_results,
                                               _IGNORED_TESTS)
@@ -361,8 +365,8 @@
     job_name = '%s-%s' % (job_id, getpass.getuser())
     log_link = URL_PATTERN % (rpc_client_lib.add_protocol(URL_HOST), job_name)
     try:
-        urllib2.urlopen(log_link).read()
-    except urllib2.URLError:
+        urllib.request.urlopen(log_link).read()
+    except urllib.error.URLError:
         summary.append('Failed to load page for link to log: %s.' % log_link)
 
     if summary:
@@ -400,7 +404,7 @@
         return
     exc_info = queue.get()
     # Raise the exception with original backtrace.
-    print 'Original stack trace of the exception:\n%s' % exc_info[2]
+    print('Original stack trace of the exception:\n%s' % exc_info[2])
     raise exc_info[0](exc_info[1])
 
 
@@ -504,7 +508,7 @@
         check_dut_inventory(arguments.num_duts, arguments.pool)
         _run_test_suites(arguments)
         check_service_crash(arguments.service_respawn_limit, start_time)
-        print _SUCCESS_MSG
+        print(_SUCCESS_MSG)
     except Exception:
         # Abort running jobs unless flagged to continue when there is a failure.
         if not arguments.continue_on_failure:
diff --git a/site_utils/test_push_common.py b/site_utils/test_push_common.py
index f22614c..715aa6b 100644
--- a/site_utils/test_push_common.py
+++ b/site_utils/test_push_common.py
@@ -1,3 +1,4 @@
+# Lint as: python2, python3
 # Copyright 2018 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -8,8 +9,12 @@
 skylab: venv/skylab_staging/test_push.py
 """
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
 import collections
 import re
+import six
 
 # Dictionary of test results keyed by test name regular expression.
 EXPECTED_TEST_RESULTS = {'^SERVER_JOB$':                 ['GOOD'],
@@ -74,7 +79,7 @@
     mismatch_errors = []
     unknown_tests = []
     found_keys = set()
-    for test_name, test_status_list in test_views.iteritems():
+    for test_name, test_status_list in six.iteritems(test_views):
         test_found = False
         for test_name_pattern, expected_result in expected_results.items():
             if re.search(test_name_pattern, test_name):
diff --git a/site_utils/test_push_unittest.py b/site_utils/test_push_unittest.py
index 32f353f..fbc3d31 100755
--- a/site_utils/test_push_unittest.py
+++ b/site_utils/test_push_unittest.py
@@ -3,10 +3,10 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import StringIO
+import six
 import mox
 import unittest
-import urllib2
+from six.moves import urllib
 
 import mock
 
@@ -47,9 +47,9 @@
 
         """
         self.mox.UnsetStubs()
-        response = StringIO.StringIO('some_value')
-        self.mox.StubOutWithMock(urllib2, 'urlopen')
-        urllib2.urlopen(mox.IgnoreArg()).AndReturn(response)
+        response = six.StringIO('some_value')
+        self.mox.StubOutWithMock(urllib.request, 'urlopen')
+        urllib.request.urlopen(mox.IgnoreArg()).AndReturn(response)
 
         self.mox.StubOutWithMock(test_push, 'check_dut_image')
         test_push.check_dut_image(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(
diff --git a/site_utils/test_runner_utils.py b/site_utils/test_runner_utils.py
index 802cde6..7d6f2d8 100755
--- a/site_utils/test_runner_utils.py
+++ b/site_utils/test_runner_utils.py
@@ -1,7 +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 errno
 import os
 import re
@@ -31,6 +36,7 @@
 from autotest_lib.server import server_logging_config
 from autotest_lib.server import utils
 from autotest_lib.utils import labellib
+from six.moves import range
 
 
 _autoserv_proc = None
@@ -463,7 +469,7 @@
     @param ssh_private_key: Path to the ssh private key to use for testing.
     """
     # Add the testing key to the current ssh agent.
-    if os.environ.has_key('SSH_AGENT_PID'):
+    if 'SSH_AGENT_PID' in os.environ:
         # Copy the testing key to the temp directory and make it NOT
         # world-readable. Otherwise, ssh-add complains.
         shutil.copy(ssh_private_key, temp_directory)
diff --git a/site_utils/test_runner_utils_unittest.py b/site_utils/test_runner_utils_unittest.py
index 6f75fe8..2c87bad 100755
--- a/site_utils/test_runner_utils_unittest.py
+++ b/site_utils/test_runner_utils_unittest.py
@@ -4,6 +4,9 @@
 # found in the LICENSE file.
 # pylint: disable-msg=C0111
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
 import os, unittest
 import mox
 import common
@@ -15,6 +18,8 @@
 from autotest_lib.server.cros.dynamic_suite import suite as suite_module
 from autotest_lib.server.hosts import host_info
 from autotest_lib.site_utils import test_runner_utils
+from six.moves import range
+from six.moves import zip
 
 
 class StartsWithList(mox.Comparator):
@@ -47,7 +52,7 @@
         if len(rhs)<n:
             return False
         return any((self._sublist == rhs[i:i+n])
-                   for i in xrange(len(rhs) - n + 1))
+                   for i in range(len(rhs) - n + 1))
 
 class DummyJob(object):
     def __init__(self, id=1):
diff --git a/site_utils/test_that.py b/site_utils/test_that.py
index 7a2e6a6..64a01a3 100755
--- a/site_utils/test_that.py
+++ b/site_utils/test_that.py
@@ -3,6 +3,10 @@
 # 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 argparse
 import os
 import signal
@@ -253,7 +257,7 @@
     @param arguments: Parsed command line arguments.
     """
     if not os.path.exists('/etc/cros_chroot_version'):
-        print >> sys.stderr, 'For local runs, script must be run inside chroot.'
+        print('For local runs, script must be run inside chroot.', file=sys.stderr)
         return 1
 
     results_directory = test_runner_utils.create_results_directory(
@@ -281,8 +285,8 @@
         sysroot_path = os.path.join('/build', arguments.board, '')
 
         if not os.path.exists(sysroot_path):
-            print >> sys.stderr, ('%s does not exist. Have you run '
-                                  'setup_board?' % sysroot_path)
+            print(('%s does not exist. Have you run '
+                   'setup_board?' % sysroot_path), file=sys.stderr)
             return 1
 
         path_ending = 'usr/local/build/autotest'
@@ -291,10 +295,10 @@
     site_utils_path = os.path.join(autotest_path, 'site_utils')
 
     if not os.path.exists(autotest_path):
-        print >> sys.stderr, ('%s does not exist. Have you run '
-                              'build_packages? Or if you are using '
-                              '--autotest_dir, make sure it points to '
-                              'a valid autotest directory.' % autotest_path)
+        print(('%s does not exist. Have you run '
+               'build_packages? Or if you are using '
+               '--autotest_dir, make sure it points to '
+               'a valid autotest directory.' % autotest_path), file=sys.stderr)
         return 1
 
     realpath = os.path.realpath(__file__)
@@ -378,7 +382,7 @@
     try:
         validate_arguments(arguments)
     except ValueError as err:
-        print >> sys.stderr, ('Invalid arguments. %s' % err.message)
+        print(('Invalid arguments. %s' % str(err)), file=sys.stderr)
         return 1
 
     if arguments.remote == ':lab:':