← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~googol/openlp/jenkins-script into lp:openlp

 

Andreas Preikschat has proposed merging lp:~googol/openlp/jenkins-script into lp:openlp.

Requested reviews:
  Tim Bentley (trb143)

For more details, see:
https://code.launchpad.net/~googol/openlp/jenkins-script/+merge/213525

Hello,

- added a script to trigger jenkins


[SUCCESS] http://ci.openlp.org/job/Branch-01-Pull/191/
[SUCCESS] http://ci.openlp.org/job/Branch-02-Functional-Tests/164/
[SUCCESS] http://ci.openlp.org/job/Branch-03-Interface-Tests/113/
[SUCCESS] http://ci.openlp.org/job/Branch-04-Windows_Tests/75/

-- 
https://code.launchpad.net/~googol/openlp/jenkins-script/+merge/213525
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/common/registry.py'
--- openlp/core/common/registry.py	2014-03-17 19:05:55 +0000
+++ openlp/core/common/registry.py	2014-03-31 17:33:09 +0000
@@ -62,11 +62,9 @@
         registry = cls()
         registry.service_list = {}
         registry.functions_list = {}
-        registry.running_under_test = False
+        # Allow the tests to remove Registry entries but not the live system
+        registry.running_under_test = 'nose' in sys.argv[0]
         registry.initialising = True
-        # Allow the tests to remove Registry entries but not the live system
-        if 'nose' in sys.argv[0]:
-            registry.running_under_test = True
         return registry
 
     def get(self, key):
@@ -128,7 +126,7 @@
         :param event: The function description..
         :param function: The function to be called when the event happens.
         """
-        if self.running_under_test is False:
+        if not self.running_under_test:
             trace_error_handler(log)
             log.error('Invalid Method call for key %s' % event)
             raise KeyError('Invalid Method call for key %s' % event)

=== modified file 'scripts/check_dependencies.py'
--- scripts/check_dependencies.py	2013-12-24 08:56:50 +0000
+++ scripts/check_dependencies.py	2014-03-31 17:33:09 +0000
@@ -94,6 +94,7 @@
     ('psycopg2', '(PostgreSQL support)', True),
     ('nose', '(testing framework)', True),
     ('mock',  '(testing module)', sys.version_info[1] < 3),
+    ('jenkins', '(access jenkins api - package name: enkins-webapi)', True),
 ]
 
 w = sys.stdout.write

=== added file 'scripts/jenkins_script.py'
--- scripts/jenkins_script.py	1970-01-01 00:00:00 +0000
+++ scripts/jenkins_script.py	2014-03-31 17:33:09 +0000
@@ -0,0 +1,193 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection                                      #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2014 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan      #
+# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub,      #
+# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer.   #
+# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru,          #
+# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith,             #
+# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock,              #
+# Frode Woldsund, Martin Zibricky, Patrick Zimmermann                         #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it     #
+# under the terms of the GNU General Public License as published by the Free  #
+# Software Foundation; version 2 of the License.                              #
+#                                                                             #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
+# more details.                                                               #
+#                                                                             #
+# You should have received a copy of the GNU General Public License along     #
+# with this program; if not, write to the Free Software Foundation, Inc., 59  #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
+###############################################################################
+"""
+This script helps to trigger builds of branches. To use it you have to install the jenkins-webapi package:
+
+    pip3 install jenkins-webapi
+
+You probably want to create an alias. Add this to your ~/.bashrc file and then logout and login (to apply the alias):
+
+    alias ci="python3 ./scripts/jenkins_script.py TOKEN"
+
+You can look up the token in the Branch-01-Pull job configuration or ask in IRC.
+"""
+
+from optparse import OptionParser
+from requests.exceptions import HTTPError
+from subprocess import Popen, PIPE
+import sys
+import time
+
+from jenkins import Jenkins
+
+
+JENKINS_URL = 'http://ci.openlp.org/'
+
+
+class OpenLPJobs(object):
+    """
+    This class holds any jobs we have on jenkins and we actually need in this script.
+    """
+    Branch_Pull = 'Branch-01-Pull'
+    Branch_Functional = 'Branch-02-Functional-Tests'
+    Branch_Interface = 'Branch-03-Interface-Tests'
+    Branch_Windows = 'Branch-04-Windows_Tests'
+    Branch_PEP = 'Branch-05-Code-Analysis'
+
+    Jobs = [Branch_Pull, Branch_Functional, Branch_Interface, Branch_Windows, Branch_PEP]
+
+
+class JenkinsTrigger(object):
+    def __init__(self, token):
+        """
+        Create the JenkinsTrigger instance.
+
+        :param token: The token we need to trigger the build. If you do not have this token, ask in IRC.
+        """
+        self.token = token
+        self.repo_name = get_repo_name()
+        self.jenkins_instance = Jenkins(JENKINS_URL)
+
+    def trigger_build(self):
+        """
+        Ask our jenkins server to build the "Branch-01-Pull" job.
+        """
+        self.jenkins_instance.job(OpenLPJobs.Branch_Pull).build({'BRANCH_NAME': self.repo_name}, token=self.token)
+
+    def print_output(self):
+        """
+        Print the status information of the build tirggered.
+        """
+        print("Add this to your merge proposal:")
+        print("--------------------------------")
+        for job in OpenLPJobs.Jobs:
+            self.__print_build_info(job)
+
+    def open_browser(self):
+        """
+        Opens the browser.
+        """
+        url = self.jenkins_instance.job(OpenLPJobs.Branch_Pull).info['url']
+        # Open the url
+        Popen(('xdg-open', url), stderr=PIPE)
+
+    def __print_build_info(self, job_name):
+        """
+        This helper method prints the job information of the given ``job_name``
+
+        :param job_name: The name of the job we want the information from. For example *Branch-01-Pull*. Use the class
+         variables from the :class:`OpenLPJobs` class.
+        """
+        job = self.jenkins_instance.job(job_name)
+        while job.info['inQueue']:
+            # Give other processes the possibility to take over. Like Thread.yield().
+            time.sleep(0)
+        build = job.last_build
+        build.wait()
+        result_string = build.info['result']
+        url = build.info['url']
+        print('[%s] %s' % (result_string, url))
+        # On failure open the browser.
+        #if result_string == "FAILURE":
+        #    url += 'console'
+        #    Popen(('xdg-open', url), stderr=PIPE)
+
+
+def get_repo_name():
+    """
+    This returns the name of branch of the wokring directory. For example it returns *lp:~googol/openlp/render*.
+    """
+    # Run the bzr command.
+    bzr = Popen(('bzr', 'info'), stdout=PIPE, stderr=PIPE)
+    raw_output, error = bzr.communicate()
+    # Detect any errors
+    if error:
+        print('This is not a branch.')
+        return
+    # Clean the output.
+    raw_output = raw_output.decode()
+    output_list = list(map(str.strip, raw_output.split('\n')))
+    # Determine the branch's name
+    repo_name = ''
+    for line in output_list:
+        # Check if it is remote branch.
+        if 'push branch' in line:
+            repo_name = line.replace('push branch: bzr+ssh://bazaar.launchpad.net/', 'lp:')
+            break
+        # Check if trunk. Note, bzr info can return both 'push branch' as well as 'checkout of branch'. The later can
+        # occur before the first. So we do not want to break here to make sure we find any orrucances of
+        elif 'checkout of branch' in line:
+            repo_name = line.replace('checkout of branch: bzr+ssh://bazaar.launchpad.net/+branch/', 'lp:')
+    repo_name = repo_name.strip('/')
+
+    # Did we find the branch name?
+    if not repo_name:
+        for line in output_list:
+            # Check if the branch was pushed.
+            if 'Shared repository with trees (format: 2a)' in line:
+                print('Not a branch. cd to a branch.')
+                return
+        print('Not a branch. Have you pushed it to launchpad?')
+        return
+    return repo_name
+
+
+def main():
+    usage = 'Usage: python %prog TOKEN [options]'
+
+    parser = OptionParser(usage=usage)
+    parser.add_option('-d', '--disable-output', dest='enable_output', action="store_false", default=True,
+                      help='Disable output.')
+    parser.add_option('-b', '--open-browser', dest='open_browser', action="store_true", default=False,
+                      help='Opens the jenkins page in your browser.')
+    #parser.add_option('-e', '--open-browser-on-error', dest='open_browser_on_error', action="store_true", default=False,
+    #                  help='Opens the jenkins page in your browser in case a test fails.')
+    options, args = parser.parse_args(sys.argv)
+
+    if len(args) == 2:
+        if not get_repo_name():
+            return
+        token = args[-1]
+        jenkins_trigger = JenkinsTrigger(token)
+        try:
+            jenkins_trigger.trigger_build()
+        except HTTPError as e:
+            print("Wrong token.")
+            return
+        # Open the browser before printing the output.
+        if options.open_browser:
+            jenkins_trigger.open_browser()
+        if options.enable_output:
+            jenkins_trigger.print_output()
+    else:
+        parser.print_help()
+
+if __name__ == '__main__':
+    main()

=== modified file 'tests/functional/openlp_core_common/test_registry.py'
--- tests/functional/openlp_core_common/test_registry.py	2014-01-03 21:33:40 +0000
+++ tests/functional/openlp_core_common/test_registry.py	2014-03-31 17:33:09 +0000
@@ -100,6 +100,20 @@
         # THEN: I expect then function to have been called and a return given
         self.assertEqual(return_value[0], 'function_2', 'A return value is provided and matches')
 
+    def remove_function_test(self):
+        """
+        Test the remove_function() method
+        """
+        # GIVEN: An existing registry register a function
+        Registry.create()
+        Registry().register_function('test1', self.dummy_function_1)
+
+        # WHEN: Remove the function.
+        Registry().remove_function('test1', self.dummy_function_1)
+
+        # THEN: The method should not be available.
+        assert not Registry().functions_list['test1'], 'The function should not be in the dict anymore.'
+
     def dummy_function_1(self):
         return "function_1"