3
# Ubuntu Testing Automation Harness
4
# Copyright 2013 Canonical Ltd.
6
# This program is free software: you can redistribute it and/or modify it
7
# under the terms of the GNU General Public License version 3, as published
8
# by the Free Software Foundation.
10
# This program is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranties of
12
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
13
# PURPOSE. See the GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License along
16
# with this program. If not, see <http://www.gnu.org/licenses/>.
27
from distro_info import UbuntuDistroInfo
28
DEV_SERIES = UbuntuDistroInfo().devel()
32
"""Create and return command line parser.
34
:returns: command line parser
35
:rtype: argparse.ArgumentParser
38
parser = argparse.ArgumentParser(
39
description='Create/Update upgrade testing jenkins jobs.')
40
parser.add_argument("-d", "--dryrun", action="store_true",
41
help="Dry run mode. Don't execute jenkins commands.")
42
parser.add_argument("-u", "--username",
43
help="username to use when logging into Jenkins.")
44
parser.add_argument("-p", "--password",
45
help="username to use when logging into Jenkins")
46
parser.add_argument("--dashboard-key", default="",
47
help="The api-key for dashboard updates")
48
parser.add_argument("--nfss-config", default="",
49
help="The path to the config file for nfss insertion")
50
parser.add_argument("-b", "--branch", default="lp:ubuntu-test-cases/touch",
51
help="The branch this is located. default=%(default)s")
52
parser.add_argument("-c", "--config", required=True,
53
type=argparse.FileType('r'),
54
help="The job config to use.")
55
parser.add_argument("-P", "--publish", action="store_true",
56
help="Publish at the end of the job")
57
parser.add_argument("--prefix",
58
help="Prefix to add to the beginning of the job name")
59
parser.add_argument("-s", "--series", default=DEV_SERIES,
60
help=("series of Ubuntu to download "
61
"(default=%(default)s)"))
62
parser.add_argument("-w", "--wait", type=int, default=300,
63
help=("How long to wait after jenkins triggers the"
64
"install-and-boot job (default=%(default)d)"))
68
def _get_jenkins(url, username, password):
69
logging.info('Attempting to login to jenkins at %s', url)
70
if username is not None:
71
logging.info('...with authentication as user: %s', username)
72
instance = jenkins.Jenkins(url, username=username, password=password)
74
logging.info('...without authentication')
75
instance = jenkins.Jenkins(url)
80
def _get_environment():
81
base = os.path.join(os.path.dirname(__file__), 'templates')
82
return jinja2.Environment(
83
loader=jinja2.FileSystemLoader(base),
84
undefined=jinja2.StrictUndefined,
88
def _publish(instance, env, args, template, jobname, **params):
89
tmpl = env.get_template(template)
90
cfg = tmpl.render(**params)
92
_dryrun_func(jobname, cfg)
94
if instance.job_exists(jobname):
95
logging.info('reconfiguring job %s', jobname)
96
instance.reconfig_job(jobname, cfg)
98
logging.info('creating job %s', jobname)
99
instance.create_job(jobname, cfg)
102
def _configure_smoke(instance, env, args, config_item, device):
103
defserial = '$(${BZRDIR}/scripts/get-adb-id ${NODE_NAME})'
106
'name': device['slave-label'],
107
'device_type': device['name'],
108
'serial': device.get('serial', defserial),
109
'publish': args.publish,
110
'branch': args.branch,
111
'imagetype': config_item['image-type'],
112
'series': args.series,
113
'image_opt': config_item.get('IMAGE_OPT', ''),
114
'statsd_key': config_item.get('statsd-key', ''),
115
'dashboard_host': config_item.get('dashboard-host', ''),
116
'dashboard_port': config_item.get('dashboard-port', ''),
117
'dashboard_prefix': config_item.get('dashboard-prefix', ''),
118
'dashboard_user': config_item.get('dashboard-user', ''),
119
'dashboard_key': args.dashboard_key,
120
'nfss_config': args.nfss_config,
125
prefix = args.prefix + "-"
127
job = '{}{}-{}-{}-smoke-daily'.format(
128
prefix, args.series, config_item['image-type'], device['name'])
129
_publish(instance, env, args, 'touch-smoke.xml.jinja2', job, **params)
133
def _configure_qa_job(instance, env, args, config_item, device, test):
134
defserial = '$(${BZRDIR}/scripts/get-adb-id ${NODE_NAME})'
135
# If the slave is specified for this test, set it
136
slave = getattr(test, 'device', device['slave-label'])
139
'device_type': device['name'],
140
'serial': device.get('serial', defserial),
141
'publish': args.publish,
142
'branch': args.branch,
143
'imagetype': config_item['image-type'],
144
'series': args.series,
145
'image_opt': config_item.get('IMAGE_OPT', ''),
146
'timeout': test.timeout,
148
'nfss_config': args.nfss_config,
152
prefix = args.prefix + "-"
153
job = test.fmt.format(prefix=prefix,
156
imagetype=config_item['image-type'],
158
_publish(instance, env, args, 'touch-base.xml.jinja2', job, **params)
162
def _configure_qa_jobs(instance, env, args, config_item, device):
163
tests = list(testconfig.TESTSUITES)
164
tests = testconfig.filter_tests(tests, config_item['image-type'],
166
tests = [t for t in tests if not t.smoke]
169
j = _configure_qa_job(instance, env, args, config_item, device, t)
174
def _configure_master(instance, env, args, config_item, device, smoke, jobs):
176
'branch': args.branch,
177
'trigger_url': device.get('trigger_url', ''),
181
'num_workers': device.get('num-workers', 1),
185
prefix = args.prefix + "-"
186
job = testconfig.DEF_FMT.format(prefix=prefix,
189
imagetype=config_item['image-type'],
191
_publish(instance, env, args, 'touch-master.xml.jinja2', job, **params)
195
def _dryrun_func(jobname, config):
196
logging.debug(jobname)
197
logging.debug(config)
201
logging.basicConfig(level=logging.DEBUG)
202
args = _get_parser().parse_args()
204
config = imp.load_source('', 'config.py', args.config)
205
if args.series not in config.MATRIX:
206
print('"%s" series is not supported by this config.' % args.series)
209
jenkins_inst = _get_jenkins(config.JENKINS, args.username, args.password)
211
jenkins_inst.create_job = _dryrun_func
212
jenkins_inst.reconfig_job = _dryrun_func
214
env = _get_environment()
216
for item in config.MATRIX[args.series]:
217
for device in item['devices']:
218
job = _configure_smoke(jenkins_inst, env, args, item, device)
220
if item.get('include-qa'):
221
jobs = _configure_qa_jobs(
222
jenkins_inst, env, args, item, device)
223
_configure_master(jenkins_inst, env, args, item, device, job, jobs)
225
if __name__ == '__main__':