#!/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()