Reland "[Autotest] Migrating client/bin/job.py to python3"
This is a reland of 96cdb58d2e41d7aae5bd276ba2aa48eaba12e791
Fixed the issue which resulted in a revert.
TEST=local testing with custom .py's. Unfortunantly, with this fix, and
with the old ToT (ie, prior to the bad CL landing), it fails when I
forced it to rebuild the deps on "Unhandled KeyError: 'SYSROOT'".
I am guessing this is a var set within the lxc/drone.
However, the custom testing I did showed the issue and that this will
fix it, and be py3 compatible.
Original change's description:
> [Autotest] Migrating client/bin/job.py to python3
>
> This is causing issues. Making the file solo to help debug CQ problems
>
> BUG=chromium:990593
> TEST= py_compile in py2 and py3. Applicable unittests. CQ. dummy_Pass
>
> Change-Id: I90856bc5652965770fc8300423bba6c61fc21548
> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/2424744
> Reviewed-by: Gregory Nisbet <gregorynisbet@google.com>
> Commit-Queue: Derek Beckett <dbeckett@chromium.org>
> Tested-by: Derek Beckett <dbeckett@chromium.org>
> Auto-Submit: Derek Beckett <dbeckett@chromium.org>
Bug: chromium:990593
Change-Id: I22c0703b55341e08236413d56a704149242cd075
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/2450830
Reviewed-by: Gregory Nisbet <gregorynisbet@google.com>
Reviewed-by: Ilja H. Friedel <ihf@chromium.org>
Commit-Queue: Ilja H. Friedel <ihf@chromium.org>
Tested-by: Ilja H. Friedel <ihf@chromium.org>
diff --git a/client/bin/job.py b/client/bin/job.py
index b634b5e..948db53 100644
--- a/client/bin/job.py
+++ b/client/bin/job.py
@@ -1,3 +1,4 @@
+# Lint as: python2, python3
"""The main job wrapper
This is the core infrastructure.
@@ -21,6 +22,8 @@
import types
import weakref
+import six
+
import common
from autotest_lib.client.bin import client_logging_config
from autotest_lib.client.bin import harness
@@ -130,7 +133,7 @@
self._pre_record_init(control, options)
try:
self._post_record_init(control, options, drop_caches)
- except Exception, err:
+ except Exception as err:
self.record(
'ABORT', None, None,'client.bin.job.__init__ failed: %s' %
str(err))
@@ -479,10 +482,15 @@
raise error.TestError("Dependency %s does not exist" % dep)
os.chdir(dep_dir)
- if execfile('%s.py' % dep, {}) is None:
+ # Run the dependency, as it could create more files needed for the
+ # tests.
+ # In future this might want to be changed, as this always returns
+ # None, unless the dep.py errors. In which case, it'll error rather
+ # than returning.
+ if eval(compile(open('%s.py' % dep, "rb").read(),
+ '%s.py' % dep, 'exec'), {}) is None:
logging.info('Dependency %s successfuly built', dep)
-
def _runtest(self, url, tag, timeout, args, dargs):
try:
l = lambda : test.runtest(self, url, tag, args, dargs)
@@ -495,7 +503,7 @@
raise
except error.JobError:
raise # Caught further up and turned into an ABORT.
- except Exception, e:
+ except Exception as e:
# Converts all other exceptions thrown by the test regardless
# of phase into a TestError(TestBaseException) subclass that
# reports them with their full stack trace.
@@ -545,7 +553,7 @@
def group_func():
try:
self._runtest(url, tag, timeout, args, dargs)
- except error.TestBaseException, detail:
+ except error.TestBaseException as detail:
# The error is already classified, record it properly.
self.record(detail.exit_status, subdir, testname, str(detail))
raise
@@ -623,7 +631,7 @@
try:
self._rungroup(subdir, testname, group_func, timeout)
return 'GOOD'
- except error.TestBaseException, detail:
+ except error.TestBaseException as detail:
return detail.exit_status
@@ -654,13 +662,13 @@
result = function(*args, **dargs)
self.record('END GOOD', subdir, testname)
return result
- except error.TestBaseException, e:
+ except error.TestBaseException as e:
self.record('END %s' % e.exit_status, subdir, testname)
raise
- except error.JobError, e:
+ except error.JobError as e:
self.record('END ABORT', subdir, testname)
raise
- except Exception, e:
+ except Exception as e:
# This should only ever happen due to a bug in the given
# function's code. The common case of being called by
# run_test() will never reach this. If a control file called
@@ -697,7 +705,7 @@
raise
# If there was a different exception, turn it into a TestError.
# It will be caught by step_engine or _run_step_fn.
- except Exception, e:
+ except Exception as e:
raise error.UnhandledTestError(e)
@@ -847,7 +855,7 @@
# wait for the task to finish
try:
self._forkwait(pid, kwargs.get('timeout'))
- except Exception, e:
+ except Exception as e:
logging.info('pid %d completed with error', pid)
exceptions.append(e)
# copy the logs from the subtask into the main log
@@ -879,7 +887,7 @@
# write out a job HTML report
try:
html_report.create_report(self.resultdir)
- except Exception, e:
+ except Exception as e:
logging.error("Error writing job HTML report: %s", e)
# We are about to exit 'complete' so clean up the control file.
@@ -946,7 +954,7 @@
# defined globally can be used as a next step.
if callable(fn):
fn = fn.__name__
- if not isinstance(fn, types.StringTypes):
+ if not isinstance(fn, six.string_types):
raise StepError("Next steps must be functions or "
"strings containing the function name")
ancestry = copy.copy(self._current_step_ancestry)
@@ -990,9 +998,9 @@
return local_vars['__ret']
except SystemExit:
raise # Send error.JobContinue and JobComplete on up to runjob.
- except error.TestNAError, detail:
+ except error.TestNAError as detail:
self.record(detail.exit_status, None, fn, str(detail))
- except Exception, detail:
+ except Exception as detail:
raise error.UnhandledJobError(detail)
@@ -1062,12 +1070,13 @@
'args': self.args}
exec(JOB_PREAMBLE, global_control_vars, global_control_vars)
try:
- execfile(self.control, global_control_vars, global_control_vars)
- except error.TestNAError, detail:
+ exec(compile(open(self.control, "rb").read(), self.control, 'exec'),
+ global_control_vars, global_control_vars)
+ except error.TestNAError as detail:
self.record(detail.exit_status, None, self.control, str(detail))
except SystemExit:
raise # Send error.JobContinue and JobComplete on up to runjob.
- except Exception, detail:
+ except Exception as detail:
# Syntax errors or other general Python exceptions coming out of
# the top level of the control file itself go through here.
raise error.UnhandledJobError(detail)
@@ -1223,7 +1232,7 @@
except error.JobComplete:
sys.exit(1)
- except error.JobError, instance:
+ except error.JobError as instance:
logging.error("JOB ERROR: " + str(instance))
if myjob:
command = None
@@ -1236,7 +1245,7 @@
else:
sys.exit(1)
- except Exception, e:
+ except Exception as e:
# NOTE: job._run_step_fn and job.step_engine will turn things into
# a JobError for us. If we get here, its likely an autotest bug.
msg = str(e) + '\n' + traceback.format_exc()