From: Kirill Spitsin Date: Mon, 27 May 2013 07:25:55 +0000 (+0300) Subject: Added system tests. X-Git-Tag: v0.2.23~238^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=54d64b6125521e18f34355e97b160d23b6938c8f;p=tools%2Fpython-jenkinsapi.git Added system tests. They also can be called acceptance or functional tests. I have always found testing terminology somewhat entangled :) These test are running against an instance of real jenkins, which is launched in the beginning of the test suite and terminated in the end. jenkins.war file is automatically downloaded in case it isn't already present in jenkinsapi_tests/systests directory. There are just few tests for now. This commit is more like a demonstration of the concept. Nose (pip install nose) is needed for running the tests. After installing it tests can be run with 'nosetests' command from top-level project directory. --- diff --git a/.gitignore b/.gitignore index c256a83..a88dcba 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ /dist .settings *.DS_Store +jenkins.war diff --git a/jenkinsapi_tests/systests/__init__.py b/jenkinsapi_tests/systests/__init__.py new file mode 100644 index 0000000..d1f2514 --- /dev/null +++ b/jenkinsapi_tests/systests/__init__.py @@ -0,0 +1,58 @@ +import os +import time +import shutil +import tempfile +import subprocess + + +class Timeout(RuntimeError): + pass + + +class JenkinsLauncher(object): + + def __init__(self, timeout=10, update_war=False, launch=False): + self.timeout = timeout + self.directory = os.path.dirname(__file__) + if update_war: + self.update_war() + if launch: + self.launch() + + def update_war(self): + os.chdir(self.directory) + subprocess.check_call('./get-jenkins-war.sh') + + def launch(self): + ''' + Launches jenkins and waits while it's ready. + ''' + self.jenkins_home = tempfile.mkdtemp(prefix='jenkins-home-') + os.environ['JENKINS_HOME'] = self.jenkins_home + jenkins_command = 'java -jar jenkins.war' + self.jenkins_process = subprocess.Popen( + jenkins_command.split(), stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + start_time = time.time() + while time.time() - start_time < self.timeout: + line = self.jenkins_process.stderr.readline().strip() + if line == 'INFO: Jenkins is fully up and running': + return + raise Timeout('Timeout error occured while waiting for Jenkins start.') + + def stop(self): + shutil.rmtree(self.jenkins_home) + self.jenkins_process.terminate() + self.jenkins_process.wait() + + +launcher = None + + +def setUpPackage(): + global launcher + launcher = JenkinsLauncher(update_war=True, launch=True) + + +def tearDownPackage(): + launcher.stop() diff --git a/jenkinsapi_tests/systests/base.py b/jenkinsapi_tests/systests/base.py new file mode 100644 index 0000000..f66cd69 --- /dev/null +++ b/jenkinsapi_tests/systests/base.py @@ -0,0 +1,52 @@ +import unittest +from jenkinsapi.jenkins import Jenkins + + +EMPTY_JOB_CONFIG = '''\ + + + + + false + + + true + false + false + false + + false + + + + +''' + + +class BaseSystemTest(unittest.TestCase): + + def setUp(self): + self.jenkins = Jenkins('http://localhost:8080') + + def tearDown(self): + self._delete_all_jobs() + + def _delete_all_jobs(self): + self.jenkins.poll() + for name in self.jenkins.get_jobs_list(): + self.jenkins.delete_job(name) + + def _create_job(self, name='whatever', config=EMPTY_JOB_CONFIG): + job = self.jenkins.create_job(name, config) + self.jenkins.poll() + return job + + def assertJobIsPresent(self, name): + self.jenkins.poll() + self.assertTrue(name in self.jenkins, + 'Job %r is absent in jenkins.' % name) + + def assertJobIsAbsent(self, name): + self.jenkins.poll() + self.assertTrue(name not in self.jenkins, + 'Job %r is present in jenkins.' % name) diff --git a/jenkinsapi_tests/systests/get-jenkins-war.sh b/jenkinsapi_tests/systests/get-jenkins-war.sh new file mode 100755 index 0000000..45d2b5f --- /dev/null +++ b/jenkinsapi_tests/systests/get-jenkins-war.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +JENKINS_WAR_URL="http://mirrors.jenkins-ci.org/war/latest/jenkins.war" + +if [ ! -e 'jenkins.war' ]; then + wget $JENKINS_WAR_URL +fi diff --git a/jenkinsapi_tests/systests/test_jenkins.py b/jenkinsapi_tests/systests/test_jenkins.py new file mode 100644 index 0000000..016f1d5 --- /dev/null +++ b/jenkinsapi_tests/systests/test_jenkins.py @@ -0,0 +1,41 @@ +''' +System tests for `jenkinsapi.jenkins` module. +''' +from jenkinsapi_tests.systests.base import BaseSystemTest, EMPTY_JOB_CONFIG + + +class JobTests(BaseSystemTest): + + def test_create_job(self): + self.jenkins.create_job('whatever', EMPTY_JOB_CONFIG) + self.assertJobIsPresent('whatever') + + def test_get_jobs_list(self): + self._create_job('job1') + self._create_job('job2') + job_list = self.jenkins.get_jobs_list() + self.assertEqual(['job1', 'job2'], job_list) + + def test_delete_job(self): + self._create_job('job_to_delete') + self.jenkins.delete_job('job_to_delete') + self.assertJobIsAbsent('job_to_delete') + + def test_rename_job(self): + self._create_job('job_to_rename') + self.jenkins.rename_job('job_to_rename', 'renamed_job') + self.assertJobIsAbsent('job_to_rename') + self.assertJobIsPresent('renamed_job') + + def test_copy_job(self): + self._create_job('template_job') + self.jenkins.copy_job('template_job', 'copied_job') + self.assertJobIsPresent('template_job') + self.assertJobIsPresent('copied_job') + + +class NodeTests(BaseSystemTest): + + def test_get_node_dict(self): + self.assertEqual(self.jenkins.get_node_dict(), { + 'master': 'http://localhost:8080/computer/master/api/python/'})