1# Copyright 2017 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 5import logging 6import os 7import socket 8import time 9 10from autotest_lib.client.common_lib import base_utils 11from autotest_lib.client.common_lib import global_config 12from autotest_lib.client.common_lib import time_utils 13from autotest_lib.site_utils import job_directories 14 15CONFIG=global_config.global_config 16 17RETRIEVE_LOGS_CGI = CONFIG.get_config_value( 18 'BUG_REPORTING', 'retrieve_logs_cgi', default='') 19USE_PROD_SERVER = CONFIG.get_config_value( 20 'SERVER', 'use_prod_sponge_server', default=False, type=bool) 21 22 23class AutotestJobInfo(object): 24 """Autotest job info.""" 25 26 # Tell the uploader what type of info this object holds. 27 tags=['autotest'] 28 29 # Version of the data stored. 30 version = 2 31 32 def __init__(self, job): 33 self._job = job 34 self._tasks = list( 35 self.create_task_info(test) for test in self._job.tests) 36 37 self.build = job.build 38 self.build_version = job.build_version 39 self.board = job.board 40 41 @property 42 def id(self): 43 """The id of the autotest job.""" 44 return job_directories.get_job_id_or_task_id(self._job.dir) 45 46 @property 47 def label(self): 48 """The label of the autotest job.""" 49 return self._job.label 50 51 @property 52 def user(self): 53 """The user who launched the autotest job.""" 54 return self._job.user 55 56 @property 57 def start_time(self): 58 """The utc start time of the autotest job.""" 59 return self._job.keyval_dict.get('job_started', time.time()) 60 61 @property 62 def end_time(self): 63 """The utc end time of the autotest job.""" 64 return self._job.keyval_dict.get('job_finished', time.time()) 65 66 @property 67 def dut(self): 68 """The dut for the job.""" 69 return self._job.machine 70 71 @property 72 def drone(self): 73 """The drone used to run the job.""" 74 return self._job.keyval_dict.get('drone', socket.gethostname()) 75 76 @property 77 def keyvals(self): 78 """Keyval dict for this job.""" 79 return self._job.keyval_dict 80 81 @property 82 def tasks(self): 83 """All tests that this job ran.""" 84 return self._tasks 85 86 @property 87 def results_dir(self): 88 """The directory where job results are stored.""" 89 return os.path.abspath(self._job.dir) 90 91 @property 92 def results_url(self): 93 """The url where results are stored.""" 94 return '%sresults/%s-%s/%s' % ( 95 RETRIEVE_LOGS_CGI, self.id, self.user, self.dut) 96 97 @property 98 def is_official(self): 99 """If this is a production result.""" 100 return USE_PROD_SERVER 101 102 def create_task_info(self, test): 103 """Thunk for creating task info. 104 105 @param test: The autotest test. 106 107 @returns The task info. 108 """ 109 logging.info('Using default autotest task info for %s.', test.testname) 110 return AutotestTaskInfo(test, self) 111 112 113class AutotestTaskInfo(object): 114 """Info about an autotest test.""" 115 116 # Tell the uploader what type of info is kept in this task. 117 tags = ['autotest'] 118 119 # A list of logs to upload for this task. 120 logs = ['debug', 'status.log', 'crash', 'keyval', 'control', 'control.srv', 121 'results/results-chart.json'] 122 123 # Version of the data stored. 124 version = 2 125 126 def __init__(self, test, job): 127 """ 128 @param test: The autotest test to create this task from. 129 @param job: The job info that owns this task. 130 """ 131 self._test = test 132 self._job = job 133 134 keyvals_file = os.path.join(self.results_dir, 'keyval') 135 self.keyvals = base_utils.read_keyval(keyvals_file) 136 137 @property 138 def taskname(self): 139 """The name of the test.""" 140 return self._test.testname 141 142 @property 143 def status(self): 144 """The autotest status of this test.""" 145 return self._test.status 146 147 @property 148 def start_time(self): 149 """The utc recorded time of when this test started.""" 150 return time_utils.to_utc_timestamp(self._test.started_time) 151 152 @property 153 def end_time(self): 154 """The utc recorded time of when this test ended.""" 155 return time_utils.to_utc_timestamp(self._test.finished_time) 156 157 @property 158 def subdir(self): 159 """The sub directory used for this test.""" 160 return self._test.subdir 161 162 @property 163 def attributes(self): 164 """Attributes of this task.""" 165 return getattr(self._test, 'attributes', {}) 166 167 @property 168 def reason(self): 169 """The reason for this tasks status.""" 170 return getattr(self._test, 'reason', None) 171 172 @property 173 def results_dir(self): 174 """The full directory where results are stored for this test.""" 175 if self.subdir == '----' or not self.subdir: 176 return self._job.results_dir 177 else: 178 return os.path.join(self._job.results_dir, self.subdir) 179 180 @property 181 def is_test(self): 182 """True if this task is an actual test that ran.""" 183 return self.subdir != '----' 184