Save exception to a file for Downloader.IsStaged to retrieve.

When a caller makes async call to stage artifacts, exceptions raised in
_DownloadArtifactsSerially cannot be catched by caller. This CL add try-except
in artifact.Prcess to save the exception to a local file. When caller calls
Downloader.IsStaged, devserver can check if corresponding exception file exists.
If that's True, raise the Exception for caller to catch and stop waiting.

This CL must be work together with the CL in Autotest:
 https://gerrit.chromium.org/gerrit/66240

BUG=chromium:273981
TEST=test with three different cases:
1. run_suite for a legit build, e.g.,
./run_suite.py --build=lumpy-release/R30-4501.0.0 --board=lumpy --suite=dummy
wait for artifactions to download, suite job just be created successfully.
2. run_suite for a legit build, e.g.,
./run_suite.py --build=lumpy-release/R30-4501.0.0 --board=lumpy --suite=dummy
simulate connection problem by killing devserver right after downloading starts.
Restart devserver after 30 seconds or so. Artifacts should be successfully
downloaded and suite job should be created.
3. run_suite for a non-existing build, e.g.:
./run_suite.py --build=lumpy-release/R30-no_such_build --board=lumpy --suite=dummy
run_suite command should fail with following error in 5-10 seconds:
DownloaderException: GSUtilError: Failed to list payloads. GSUTIL cmd gsutil ls gs://chromeos-image-archive/lumpy-release/R30-no_such_build/* failed with return code 1:
CommandException: One or more URIs matched no objects.

Change-Id: I992fd09647cba35b7a60539e71de78e79bbdc2db
Reviewed-on: https://gerrit.chromium.org/gerrit/66239
Reviewed-by: Chris Sosa <[email protected]>
Tested-by: Dan Shi <[email protected]>
Commit-Queue: Dan Shi <[email protected]>
3 files changed