blob: 8001ca7178242a20bcf254cbfb43296e3efc14dc [file] [log] [blame]
Allen Li20dd90f2017-07-17 12:27:10 -07001# 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
Allen Li464220f2017-09-12 17:14:22 -07005"""Run a job against Autotest.
6
7See http://goto.google.com/monitor_db_per_job_refactor
Allen Li2678d362017-10-11 16:59:07 -07008
Allen Li08fd2142018-06-28 13:18:34 -07009See also https://chromium.googlesource.com/chromiumos/infra/lucifer
Allen Li2678d362017-10-11 16:59:07 -070010
Allen Li08fd2142018-06-28 13:18:34 -070011job_reporter is a thin wrapper around lucifer and only updates the
Allen Li2678d362017-10-11 16:59:07 -070012Autotest database according to status events.
Allen Li464220f2017-09-12 17:14:22 -070013"""
14
Allen Li20dd90f2017-07-17 12:27:10 -070015from __future__ import absolute_import
16from __future__ import division
17from __future__ import print_function
18
Allen Liff162b72017-11-13 12:10:33 -080019import atexit
Allen Li20dd90f2017-07-17 12:27:10 -070020import argparse
21import logging
Allen Li3f9f6222017-10-18 16:12:08 -070022import os
Allen Li20dd90f2017-07-17 12:27:10 -070023import sys
24
Allen Li464220f2017-09-12 17:14:22 -070025from lucifer import autotest
Allen Li20dd90f2017-07-17 12:27:10 -070026from lucifer import eventlib
Allen Lid31d7322017-11-20 12:48:57 -080027from lucifer import handlers
Allen Li7b88e932018-02-09 18:26:32 -080028from lucifer import jobx
Allen Lid64e4c82017-11-14 16:34:34 -080029from lucifer import leasing
Allen Li20dd90f2017-07-17 12:27:10 -070030from lucifer import loglib
31
32logger = logging.getLogger(__name__)
33
Allen Li20dd90f2017-07-17 12:27:10 -070034
Allen Li0b80a4b2018-03-01 15:22:40 -080035def main(argv):
Allen Li20dd90f2017-07-17 12:27:10 -070036 """Main function
37
Allen Li0b80a4b2018-03-01 15:22:40 -080038 @param argv: command line args
Allen Li20dd90f2017-07-17 12:27:10 -070039 """
Allen Li0b80a4b2018-03-01 15:22:40 -080040 print('job_reporter: Running with argv: %r' % argv, file=sys.stderr)
41 args = _parse_args_and_configure_logging(argv[1:])
42 logger.info('Running with parsed args: %r', args)
Allen Libda32362018-01-24 17:49:34 -080043 with leasing.obtain_lease(_lease_path(args.jobdir, args.job_id)):
Allen Li75f88082017-11-15 15:24:33 -080044 autotest.monkeypatch()
Allen Libda32362018-01-24 17:49:34 -080045 ret = _main(args)
46 logger.info('Exiting normally with: %r', ret)
47 return ret
Allen Li58e01ce2017-11-10 13:17:53 -080048
49
50def _parse_args_and_configure_logging(args):
Allen Li464220f2017-09-12 17:14:22 -070051 parser = argparse.ArgumentParser(prog='job_reporter', description=__doc__)
Allen Li20dd90f2017-07-17 12:27:10 -070052 loglib.add_logging_options(parser)
Allen Li45c2fdf2018-02-14 18:47:40 -080053
54 # General configuration
Allen Li057be2c2017-11-08 13:51:24 -080055 parser.add_argument('--jobdir', default='/usr/local/autotest/leases',
Allen Lid64e4c82017-11-14 16:34:34 -080056 help='Path to job leases directory.')
Allen Li08fd2142018-06-28 13:18:34 -070057 parser.add_argument('--lucifer-path', default='/usr/bin/lucifer',
58 help='Path to lucifer binary')
Allen Li45c2fdf2018-02-14 18:47:40 -080059
60 # Job specific
Allen Li8bb357b2018-02-28 17:17:57 -080061
62 # General
Allen Libc6599c2018-02-22 12:43:21 -080063 parser.add_argument('--lucifer-level', required=True,
Allen Li3ac00072018-05-24 14:25:09 -070064 help='Lucifer level', choices=['STARTING'])
Allen Li8bb357b2018-02-28 17:17:57 -080065 parser.add_argument('--job-id', type=int, required=True,
66 help='Autotest Job ID')
67 parser.add_argument('--results-dir', required=True,
Allen Lideb5d3b2018-03-05 16:44:50 -080068 help='Path to job results directory.')
Allen Li8bb357b2018-02-28 17:17:57 -080069
70 # STARTING flags
Allen Li164e8eb2018-02-28 17:11:19 -080071 parser.add_argument('--execution-tag', default=None,
72 help='Autotest execution tag.')
Allen Li03b91502018-05-24 14:19:39 -070073 parser.add_argument('--parsing-only', action='store_true',
74 help='Whether to only do parsing'
75 ' (only with --lucifer-level STARTING)')
Allen Li8bb357b2018-02-28 17:17:57 -080076
Allen Lidbdaab52017-11-20 12:41:00 -080077 args = parser.parse_args(args)
Allen Li20dd90f2017-07-17 12:27:10 -070078 loglib.configure_logging_with_args(parser, args)
Allen Li58e01ce2017-11-10 13:17:53 -080079 return args
Allen Li20dd90f2017-07-17 12:27:10 -070080
81
Allen Liff162b72017-11-13 12:10:33 -080082def _main(args):
83 """Main program body, running under a lease file.
84
85 @param args: Namespace object containing parsed arguments
86 """
87 ts_mon_config = autotest.chromite_load('ts_mon_config')
88 metrics = autotest.chromite_load('metrics')
89 with ts_mon_config.SetupTsMonGlobalState(
Allen Li9c860702018-02-16 15:25:15 -080090 'job_reporter', short_lived=True):
Allen Li3d089a12017-11-20 12:06:24 -080091 atexit.register(metrics.Flush)
Allen Li0d4322b2018-02-09 18:44:57 -080092 return _run_autotest_job(args)
93
94
95def _run_autotest_job(args):
96 """Run a job as seen from Autotest.
97
98 This include some Autotest setup and cleanup around lucifer starting
99 proper.
100 """
Allen Li6c17f1d2018-03-06 12:20:11 -0800101 models = autotest.load('frontend.afe.models')
102 job = models.Job.objects.get(id=args.job_id)
Allen Li3ac00072018-05-24 14:25:09 -0700103 _prepare_autotest_job_files(args, job)
Allen Li6c17f1d2018-03-06 12:20:11 -0800104 handler = _make_handler(args, job)
105 ret = _run_lucifer_job(handler, args, job)
Allen Li0d4322b2018-02-09 18:44:57 -0800106 if handler.completed:
107 _mark_handoff_completed(args.job_id)
108 return ret
Allen Liff162b72017-11-13 12:10:33 -0800109
110
Allen Li164e8eb2018-02-28 17:11:19 -0800111def _prepare_autotest_job_files(args, job):
112 jobx.prepare_control_file(job, args.results_dir)
113 jobx.prepare_keyvals_files(job, args.results_dir)
114
115
Allen Li6c17f1d2018-03-06 12:20:11 -0800116def _make_handler(args, job):
Allen Li08fd2142018-06-28 13:18:34 -0700117 """Make event handler for lucifer."""
Allen Lid31d7322017-11-20 12:48:57 -0800118 return handlers.EventHandler(
Allen Lid31d7322017-11-20 12:48:57 -0800119 metrics=handlers.Metrics(),
Allen Liff162b72017-11-13 12:10:33 -0800120 job=job,
Allen Li3ac00072018-05-24 14:25:09 -0700121 autoserv_exit=None,
Allen Li5afdf6d2018-03-23 15:02:25 -0700122 results_dir=args.results_dir,
Allen Liff162b72017-11-13 12:10:33 -0800123 )
Allen Li63e21c32017-11-10 13:20:28 -0800124
125
Allen Li6c17f1d2018-03-06 12:20:11 -0800126def _run_lucifer_job(event_handler, args, job):
Allen Li08fd2142018-06-28 13:18:34 -0700127 """Run lucifer test.
Allen Li20dd90f2017-07-17 12:27:10 -0700128
Allen Li902c6e92017-10-18 15:46:43 -0700129 Issued events will be handled by event_handler.
Allen Li20dd90f2017-07-17 12:27:10 -0700130
Allen Li464220f2017-09-12 17:14:22 -0700131 @param event_handler: callable that takes an Event
Allen Li5cebb2a2017-09-21 14:04:43 -0700132 @param args: parsed arguments
Allen Li08fd2142018-06-28 13:18:34 -0700133 @returns: exit status of lucifer
Allen Li20dd90f2017-07-17 12:27:10 -0700134 """
Allen Li08fd2142018-06-28 13:18:34 -0700135 command_args = [args.lucifer_path]
Allen Lie7dcbb62018-02-09 18:38:28 -0800136 command_args.extend([
Allen Li08fd2142018-06-28 13:18:34 -0700137 'test',
Allen Li58d29e92018-04-03 14:43:47 -0700138 '-autotestdir', '/usr/local/autotest',
Allen Li45c2fdf2018-02-14 18:47:40 -0800139
Allen Lie7dcbb62018-02-09 18:38:28 -0800140 '-abortsock', _abort_sock_path(args.jobdir, args.job_id),
Allen Lia6458b32018-02-14 14:56:34 -0800141 '-hosts', ','.join(jobx.hostnames(job)),
Allen Li45c2fdf2018-02-14 18:47:40 -0800142
Allen Lia22a9742018-02-20 17:44:24 -0800143 '-x-level', args.lucifer_level,
Allen Li58d7c912018-05-24 15:36:04 -0700144 '-resultsdir', args.results_dir,
Allen Li292b4ca2018-02-28 17:28:10 -0800145 ])
Allen Li6c17f1d2018-03-06 12:20:11 -0800146 _add_level_specific_args(command_args, args, job)
Allen Li292b4ca2018-02-28 17:28:10 -0800147 return eventlib.run_event_command(
148 event_handler=event_handler, args=command_args)
149
150
Allen Li6c17f1d2018-03-06 12:20:11 -0800151def _add_level_specific_args(command_args, args, job):
Allen Li08fd2142018-06-28 13:18:34 -0700152 """Add level specific arguments for lucifer test.
Allen Li292b4ca2018-02-28 17:28:10 -0800153
154 command_args is modified in place.
155 """
156 if args.lucifer_level == 'STARTING':
Allen Li6c17f1d2018-03-06 12:20:11 -0800157 _add_starting_args(command_args, args, job)
Allen Li292b4ca2018-02-28 17:28:10 -0800158 else:
159 raise Exception('Invalid lucifer level %s' % args.lucifer_level)
160
161
Allen Li6c17f1d2018-03-06 12:20:11 -0800162def _add_starting_args(command_args, args, job):
Allen Li08fd2142018-06-28 13:18:34 -0700163 """Add STARTING level arguments for lucifer test.
Allen Li292b4ca2018-02-28 17:28:10 -0800164
165 command_args is modified in place.
166 """
Allen Li164e8eb2018-02-28 17:11:19 -0800167 RebootAfter = autotest.load('frontend.afe.model_attributes').RebootAfter
168 command_args.extend([
169 '-x-control-file', jobx.control_file_path(args.results_dir),
170 ])
Allen Liec2422b2018-07-06 16:30:10 -0700171 if args.execution_tag is not None:
172 command_args.extend(['-x-execution-tag', args.execution_tag])
Allen Li164e8eb2018-02-28 17:11:19 -0800173 command_args.extend(['-x-job-owner', job.owner])
174 command_args.extend(['-x-job-name', job.name])
175 command_args.extend(
176 ['-x-reboot-after',
177 RebootAfter.get_string(job.reboot_after).lower()])
Allen Li03b91502018-05-24 14:19:39 -0700178 if args.parsing_only:
Allen Li1929fb32018-07-16 15:50:08 -0700179 command_args.append('-x-parse-only')
Allen Li164e8eb2018-02-28 17:11:19 -0800180 if job.run_reset:
181 command_args.append('-x-run-reset')
Allen Li164e8eb2018-02-28 17:11:19 -0800182 if jobx.is_client_job(job):
183 command_args.append('-x-client-test')
184 if jobx.needs_ssp(job):
185 command_args.append('-x-require-ssp')
186 test_source_build = job.keyval_dict().get('test_source_build', None)
187 if test_source_build:
188 command_args.extend(['-x-test-source-build', test_source_build])
189 if job.parent_job_id:
190 command_args.extend(['-x-parent-job-id', str(job.parent_job_id)])
Allen Li292b4ca2018-02-28 17:28:10 -0800191
192
Allen Li5cca8182017-11-20 13:12:51 -0800193def _mark_handoff_completed(job_id):
194 models = autotest.load('frontend.afe.models')
195 handoff = models.JobHandoff.objects.get(job_id=job_id)
196 handoff.completed = True
197 handoff.save()
198
199
Allen Lid64e4c82017-11-14 16:34:34 -0800200def _abort_sock_path(jobdir, job_id):
201 return _lease_path(jobdir, job_id) + '.sock'
202
203
204def _lease_path(jobdir, job_id):
205 return os.path.join(jobdir, str(job_id))
206
207
Allen Li20dd90f2017-07-17 12:27:10 -0700208if __name__ == '__main__':
Allen Li0b80a4b2018-03-01 15:22:40 -0800209 sys.exit(main(sys.argv))