#!/usr/bin/env python
#
# Test all of the Jenkins API features used by the
# OpenStack Infrastructure project
#
# Copyright (C) 2013 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
#
# See the License for the specific language governing permissions and
# limitations under the License.
import urllib2
import urlparse
from pprint import pprint
import time
from uuid import uuid4
import ConfigParser
import os
import re
import sys
sys.path.insert(0, '../../zuul/zuul')
from launcher.jenkins import ExtendedJenkins
sys.path.insert(0, '../../devstack-gate/')
from myjenkins import Jenkins as DGJenkins
JOB_NAME = 'test-job'
NODE_NAME = 'test-node'
class JenkinsTest(object):
def __init__(self):
self.config = ConfigParser.ConfigParser()
if len(sys.argv) < 2:
print "Usage: %s zuul.conf" % sys.argv[0]
sys.exit(1)
fp = sys.argv[1]
if os.path.exists(os.path.expanduser(fp)):
self.config.read(os.path.expanduser(fp))
server = self.config.get('jenkins', 'server')
user = self.config.get('jenkins', 'user')
apikey = self.config.get('jenkins', 'apikey')
self.jenkins = ExtendedJenkins(server, user, apikey)
self.dgjenkins = DGJenkins(server, user, apikey)
def nodeExists(self):
return self.dgjenkins.node_exists(NODE_NAME)
def createNode(self):
assert not self.nodeExists()
priv_key = '/var/lib/jenkins/.ssh/id_rsa'
self.dgjenkins.create_node(
NODE_NAME, numExecutors=1,
nodeDescription='Test node',
remoteFS='/home/jenkins',
labels='testnode',
exclusive=True,
launcher='hudson.plugins.sshslaves.SSHLauncher',
launcher_params={'port': 22,
'username': 'jenkins',
'privatekey': priv_key,
'host': 'nowhere.example.com'})
assert self.nodeExists()
def reconfigNode(self):
LABEL_RE = re.compile(r'')
config = self.dgjenkins.get_node_config(NODE_NAME)
assert '' in config
config = LABEL_RE.sub('', config)
self.dgjenkins.reconfig_node(NODE_NAME, config)
config = self.dgjenkins.get_node_config(NODE_NAME)
assert '' in config
def deleteNode(self):
assert self.nodeExists()
self.dgjenkins.delete_node(NODE_NAME)
assert not self.nodeExists()
def findBuildInQueue(self, build):
for item in self.jenkins.get_queue_info():
if 'actions' not in item:
continue
for action in item['actions']:
if 'parameters' not in action:
continue
parameters = action['parameters']
for param in parameters:
# UUID is deprecated in favor of ZUUL_UUID
if ((param['name'] in ['ZUUL_UUID', 'UUID'])
and build == param['value']):
return item
return False
def addJob(self, quiet_period):
assert not self.jobExists()
xml = open('jenkins-job.xml').read()
xml = xml % quiet_period
self.jenkins.create_job(JOB_NAME, xml)
assert self.jobExists()
def reconfigJob(self, quiet_period):
assert self.jobExists()
xml = open('jenkins-job.xml').read()
xml = xml % quiet_period
self.jenkins.reconfig_job(JOB_NAME, xml)
xml2 = self.jenkins.get_job_config(JOB_NAME)
s = '%s' % quiet_period
assert s in xml2
def jobExists(self):
return self.jenkins.job_exists(JOB_NAME)
def deleteJob(self):
assert self.jobExists()
self.jenkins.delete_job(JOB_NAME)
assert not self.jobExists()
def getJobs(self):
pprint(self.jenkins.get_jobs())
def testCancelQueue(self):
uuid = str(uuid4().hex)
self.jenkins.build_job(JOB_NAME, parameters=dict(UUID=uuid))
item = self.findBuildInQueue(uuid)
assert item
self.jenkins.cancel_queue(item['id'])
assert not self.findBuildInQueue(uuid)
def testCancelBuild(self):
uuid = str(uuid4().hex)
self.jenkins.build_job(JOB_NAME, parameters=dict(UUID=uuid))
assert self.findBuildInQueue(uuid)
for x in range(60):
if not self.findBuildInQueue(uuid):
break
assert not self.findBuildInQueue(uuid)
time.sleep(1)
buildno = self.jenkins.get_job_info(JOB_NAME)['lastBuild']['number']
info = self.jenkins.get_build_info(JOB_NAME, buildno)
assert info['building']
self.jenkins.stop_build(JOB_NAME, buildno)
time.sleep(1)
info = self.jenkins.get_build_info(JOB_NAME, buildno)
assert not info['building']
console_url = urlparse.urljoin(info['url'], 'consoleFull')
self.jenkins.jenkins_open(urllib2.Request(console_url))
self.jenkins.set_build_description(JOB_NAME, buildno,
"test description")
info = self.jenkins.get_build_info(JOB_NAME, buildno)
assert info['description'] == 'test description'
j = JenkinsTest()
if j.nodeExists():
j.deleteNode()
j.createNode()
j.reconfigNode()
j.deleteNode()
if j.jobExists():
j.deleteJob()
j.addJob(5)
j.reconfigJob(10)
j.testCancelQueue()
j.testCancelBuild()
j.deleteJob()