blob: 11d94140744e43781216c809b4bee90d34350893 [file] [log] [blame]
import json
import logging
import common
from autotest_lib.client.common_lib import autotemp
from autotest_lib.client.common_lib import global_config
# Try importing the essential bug reporting libraries. Chromite and gdata_lib
# are useless unless they can import gdata too.
try:
__import__('chromite')
__import__('gdata')
except ImportError, e:
fundamental_libs = False
logging.debug('Will not be able to generate link '
'to the buildbot page when filing bugs. %s', e)
else:
from chromite.lib import cros_build_lib, gs
fundamental_libs = True
# Number of times to retry if a gs command fails. Defaults to 10,
# which is far too long given that we already wait on these files
# before starting HWTests.
_GS_RETRIES = 1
_HTTP_ERROR_THRESHOLD = 400
BUG_CONFIG_SECTION = 'BUG_REPORTING'
# global configurations needed for build artifacts
_gs_domain = global_config.global_config.get_config_value(
BUG_CONFIG_SECTION, 'gs_domain', default='')
_chromeos_image_archive = global_config.global_config.get_config_value(
BUG_CONFIG_SECTION, 'chromeos_image_archive', default='')
_arg_prefix = global_config.global_config.get_config_value(
BUG_CONFIG_SECTION, 'arg_prefix', default='')
# global configurations needed for results log
_retrieve_logs_cgi = global_config.global_config.get_config_value(
BUG_CONFIG_SECTION, 'retrieve_logs_cgi', default='')
_generic_results_bin = global_config.global_config.get_config_value(
BUG_CONFIG_SECTION, 'generic_results_bin', default='')
_debug_dir = global_config.global_config.get_config_value(
BUG_CONFIG_SECTION, 'debug_dir', default='')
# cautotest url used to generate the link to the job
_cautotest_job_view = global_config.global_config.get_config_value(
BUG_CONFIG_SECTION, 'cautotest_job_view', default='')
# gs prefix to perform file like operations (gs://)
_gs_file_prefix = global_config.global_config.get_config_value(
BUG_CONFIG_SECTION, 'gs_file_prefix', default='')
# global configurations needed for buildbot stages link
_buildbot_builders = global_config.global_config.get_config_value(
BUG_CONFIG_SECTION, 'buildbot_builders', default='')
_build_prefix = global_config.global_config.get_config_value(
BUG_CONFIG_SECTION, 'build_prefix', default='')
def link_build_artifacts(build):
"""Returns a url to build artifacts on google storage.
@param build: A string, e.g. stout32-release/R30-4433.0.0
@returns: A url to build artifacts on google storage.
"""
return (_gs_domain + _arg_prefix +
_chromeos_image_archive + build)
def link_job(job_id):
"""Returns an url to the job on cautotest.
@param job_id: A string, representing the job id.
@returns: An url to the job on cautotest.
"""
if not job_id:
return 'Job did not run, or was aborted prematurely'
return '%s=%s' % (_cautotest_job_view, job_id)
def _base_results_log(job_id, result_owner, hostname):
"""Returns the base url of the job's results.
@param job_id: A string, representing the job id.
@param result_owner: A string, representing the onwer of the job.
@param hostname: A string, representing the host on which
the job has run.
@returns: The base url of the job's results.
"""
if job_id and result_owner and hostname:
path_to_object = '%s-%s/%s' % (job_id, result_owner,
hostname)
return (_retrieve_logs_cgi + _generic_results_bin +
path_to_object)
def link_result_logs(job_id, result_owner, hostname):
"""Returns a url to test logs on google storage.
@param job_id: A string, representing the job id.
@param result_owner: A string, representing the owner of the job.
@param hostname: A string, representing the host on which the
jot has run.
@returns: A url to test logs on google storage.
"""
base_results = _base_results_log(job_id, result_owner, hostname)
if base_results:
return '%s/%s' % (base_results, _debug_dir)
return ('Could not generate results log: the job with id %s, '
'scheduled by: %s on host: %s did not run' %
(job_id, result_owner, hostname))
def link_status_log(job_id, result_owner, hostname):
"""Returns an url to status log of the job.
@param job_id: A string, representing the job id.
@param result_owner: A string, representing the owner of the job.
@param hostname: A string, representing the host on which the
jot has run.
@returns: A url to status log of the job.
"""
base_results = _base_results_log(job_id, result_owner, hostname)
if base_results:
return '%s/%s' % (base_results, 'status.log')
return 'NA'
def _get_metadata_dict(build):
"""
Get a dictionary of metadata related to this failure.
Metadata.json is created in the HWTest Archiving stage, if this file
isn't found the call to Cat will timeout after the number of retries
specified in the GSContext object. If metadata.json exists we parse
a json string of it's contents into a dictionary, which we return.
@param build: A string, e.g. stout32-release/R30-4433.0.0
@returns: A dictionary with the contents of metadata.json.
"""
if not fundamental_libs:
return
try:
tempdir = autotemp.tempdir()
gs_context = gs.GSContext(retries=_GS_RETRIES,
cache_dir=tempdir.name)
gs_cmd = '%s%s%s/metadata.json' % (_gs_file_prefix,
_chromeos_image_archive,
build)
return json.loads(gs_context.Cat(gs_cmd).output)
except (cros_build_lib.RunCommandError, gs.GSContextException) as e:
logging.debug(e)
finally:
tempdir.clean()
def link_buildbot_stages(build):
"""
Link to the buildbot page associated with this run of HWTests.
@param build: A string, e.g. stout32-release/R30-4433.0.0
@return: A link to the buildbot stages page, or 'NA' if we cannot glean
enough information from metadata.json (or it doesn't exist).
"""
metadata = _get_metadata_dict(build)
if (metadata and
metadata.get('builder-name') and
metadata.get('build-number')):
return ('%s%s/builds/%s' %
(_buildbot_builders,
metadata.get('builder-name'),
metadata.get('build-number'))).replace(' ', '%20')
return 'NA'