Dan Shi | 4f46aaf | 2016-06-25 00:21:41 -0700 | [diff] [blame] | 1 | # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
| 5 | """This module contains utilities for test to report result to Sponge. |
| 6 | """ |
| 7 | |
| 8 | import logging |
Dan Shi | 4c33b6a | 2016-08-18 16:11:31 -0700 | [diff] [blame^] | 9 | import os |
Dan Shi | 4f46aaf | 2016-06-25 00:21:41 -0700 | [diff] [blame] | 10 | import socket |
| 11 | import time |
| 12 | |
| 13 | import common |
| 14 | |
| 15 | try: |
| 16 | import sponge |
| 17 | except ImportError: |
| 18 | logging.debug('Module failed to be imported: sponge') |
| 19 | sponge = None |
| 20 | |
| 21 | from autotest_lib.client.common_lib import decorators |
| 22 | from autotest_lib.client.common_lib import global_config |
| 23 | from autotest_lib.site_utils import job_directories |
| 24 | from autotest_lib.tko import models |
| 25 | from autotest_lib.tko import utils as tko_utils |
| 26 | |
| 27 | |
| 28 | CONFIG=global_config.global_config |
| 29 | |
| 30 | RETRIEVE_LOGS_CGI = CONFIG.get_config_value( |
| 31 | 'BUG_REPORTING', 'retrieve_logs_cgi', default='') |
| 32 | RESULTS_URL_FMT = RETRIEVE_LOGS_CGI + 'results/%s-%s/%s' |
| 33 | USE_PROD_SERVER = CONFIG.get_config_value( |
| 34 | 'SERVER', 'use_prod_sponge_server', default=False, type=bool) |
| 35 | |
| 36 | @decorators.test_module_available(sponge) |
| 37 | def upload_results_in_test(test, test_pass=True, acts_summary=None): |
| 38 | """Upload test results to Sponge. |
| 39 | |
| 40 | @param test: A test object. |
| 41 | @param test_pass: True if test passed, False otherwise. Default is set to |
| 42 | True. When test results are reported inside test, the test is |
| 43 | considered to success, or exception like TestFail would have been |
| 44 | raised if the test has failed. |
| 45 | @param acts_summary: Path to the json file of ACTS test summary. |
| 46 | """ |
| 47 | try: |
| 48 | # job keyval file has the information about the test job except |
| 49 | # `job_finished`, which is written after the test is actually finished. |
| 50 | # Therefore, the `end_time` for a Sponge invocation is set to current |
| 51 | # time. |
| 52 | job_keyvals = models.test.parse_job_keyval(test.resultsdir) |
| 53 | status = 'GOOD' if test_pass else 'FAIL' |
| 54 | job_id = job_directories.get_job_id_or_task_id(test.resultsdir) |
| 55 | results_dir = tko_utils.find_toplevel_job_dir(test.resultsdir) |
| 56 | dut = test.job.machines[0] if len(test.job.machines) > 0 else '' |
| 57 | results_url = RESULTS_URL_FMT % (job_id, test.job.user, dut) |
| 58 | |
| 59 | invocation_url = sponge.upload_utils.Upload( |
| 60 | job_id=job_id, |
| 61 | test_name=test.tagged_testname, |
| 62 | dut=','.join(test.job.machines), |
| 63 | drone=job_keyvals.get('drone', socket.gethostname()), |
| 64 | status=status, |
| 65 | start_time=job_keyvals['job_started'], |
| 66 | end_time=time.time(), |
| 67 | results_dir=results_dir, |
| 68 | results_url=results_url, |
| 69 | acts_summary=acts_summary, |
| 70 | use_prod_server=USE_PROD_SERVER) |
| 71 | logging.debug('Test result is uploaded to Sponge: %s', invocation_url) |
| 72 | return invocation_url |
| 73 | except Exception as e: |
| 74 | logging.exception('Failed to upload to Sponge: %s', e) |
Dan Shi | 4c33b6a | 2016-08-18 16:11:31 -0700 | [diff] [blame^] | 75 | |
| 76 | |
| 77 | @decorators.test_module_available(sponge) |
| 78 | def upload_results(job): |
| 79 | """Upload test results to Sponge with given job details. |
| 80 | |
| 81 | @param job: A job object created by tko/parsers. |
| 82 | """ |
| 83 | job_id = job_directories.get_job_id_or_task_id(job.dir) |
| 84 | results_dir = tko_utils.find_toplevel_job_dir(job.dir) |
| 85 | results_url = RESULTS_URL_FMT % (job_id, job.user, job.machine) |
| 86 | |
| 87 | # Try to locate test_run_summary.json file for android_ACTS test. |
| 88 | acts_summary = os.path.join(results_dir, 'latest', 'test_run_summary.json') |
| 89 | if not os.path.exists(acts_summary): |
| 90 | acts_summary = None |
| 91 | |
| 92 | status = 'GOOD' |
| 93 | for test in job.tests: |
| 94 | if test.status != 'GOOD': |
| 95 | status = test.status |
| 96 | break |
| 97 | |
| 98 | try: |
| 99 | invocation_url = sponge.upload_utils.Upload( |
| 100 | job_id=job_id, |
| 101 | test_name=job.label, |
| 102 | dut=job.machine, |
| 103 | drone=job.keyval_dict.get('drone', socket.gethostname()), |
| 104 | status=status, |
| 105 | start_time=job.keyval_dict['job_started'], |
| 106 | end_time=job.keyval_dict['job_finished'], |
| 107 | results_dir=results_dir, |
| 108 | results_url=results_url, |
| 109 | acts_summary=acts_summary, |
| 110 | job=job, |
| 111 | use_prod_server=USE_PROD_SERVER) |
| 112 | logging.debug('Test result is uploaded to Sponge: %s', invocation_url) |
| 113 | return invocation_url |
| 114 | except Exception as e: |
| 115 | logging.exception('Failed to upload to Sponge: %s', e) |