jhbuild r1856 - in trunk: . doc/C jhbuild jhbuild/modtypes tests



Author: fpeters
Date: Sat Jan 19 19:26:21 2008
New Revision: 1856
URL: http://svn.gnome.org/viewvc/jhbuild?rev=1856&view=rev

Log:
* doc/C/jhbuild.xml, jhbuild/config.py, jhbuild/defaults.jhbuildrc,
jhbuild/modtypes/autotools.py, jhbuild/modtypes/waf.py, tests/mock.py,
tests/tests.py: added a new makecheck_advisory option, to specify
whether failures when running "make check" should be advisory only
and not cause the module to fail; complete with documentation and unit
tests.  (closes: #310544)



Modified:
   trunk/ChangeLog
   trunk/doc/C/jhbuild.xml
   trunk/jhbuild/config.py
   trunk/jhbuild/defaults.jhbuildrc
   trunk/jhbuild/modtypes/autotools.py
   trunk/jhbuild/modtypes/waf.py
   trunk/tests/mock.py
   trunk/tests/tests.py

Modified: trunk/doc/C/jhbuild.xml
==============================================================================
--- trunk/doc/C/jhbuild.xml	(original)
+++ trunk/doc/C/jhbuild.xml	Sat Jan 19 19:26:21 2008
@@ -1212,9 +1212,16 @@
 	  <listitem>
 	    <simpara>A boolean value specifying whether to run
 	    <command>make check</command> after
-	    <command>make</command>.  This might be useful in a
-	    tinderbox-style setup.  Defaults to
-	    <constant>False</constant>.</simpara>
+	    <command>make</command>.
+	    Defaults to <constant>False</constant>.</simpara>
+	  </listitem>
+	</varlistentry>
+	<varlistentry>
+	  <term><varname>makecheck_advisory</varname></term>
+	  <listitem>
+	    <simpara>A boolean value specifying whether failures when running
+	    <command>make check</command> should be advisory only and not cause
+            a build failure.  Defaults to <constant>False</constant>.</simpara>
 	  </listitem>
 	</varlistentry>
 	<varlistentry>

Modified: trunk/jhbuild/config.py
==============================================================================
--- trunk/jhbuild/config.py	(original)
+++ trunk/jhbuild/config.py	Sat Jan 19 19:26:21 2008
@@ -1,5 +1,6 @@
 # jhbuild - a build script for GNOME 1.x and 2.x
 # Copyright (C) 2001-2006  James Henstridge
+# Copyright (C) 2007-2008  Frederic Peters
 #
 #   config.py: configuration file parser
 #
@@ -38,8 +39,9 @@
                 'tarballdir', 'pretty_print', 'svn_program', 'makedist',
                 'makedistcheck', 'nonotify', 'cvs_program',
                 'checkout_mode', 'copy_dir', 'module_checkout_mode',
-                'build_policy', 'force_policy', 'trycheckout', 'nopoison', 'quiet_mode',
-                'progress_bar']
+                'build_policy', 'force_policy', 'trycheckout',
+                'nopoison', 'makecheck_advisory',
+                'quiet_mode', 'progress_bar']
 
 env_prepends = {}
 def prependpath(envvar, path):

Modified: trunk/jhbuild/defaults.jhbuildrc
==============================================================================
--- trunk/jhbuild/defaults.jhbuildrc	(original)
+++ trunk/jhbuild/defaults.jhbuildrc	Sat Jan 19 19:26:21 2008
@@ -58,6 +58,8 @@
 nopoison      = False  # don't poison modules on failure
 force_policy  = False  # Whether to override specified build policy
 
+makecheck_advisory = False # whether to pass over 'make check' failures
+
 interact      = True   # whether to interact with the user.
 quiet_mode    = False  # whether to display running commands output
 progress_bar  = True   # whether to display a progress bar when running in quiet mode

Modified: trunk/jhbuild/modtypes/autotools.py
==============================================================================
--- trunk/jhbuild/modtypes/autotools.py	(original)
+++ trunk/jhbuild/modtypes/autotools.py	Sat Jan 19 19:26:21 2008
@@ -1,5 +1,6 @@
 # jhbuild - a build script for GNOME 1.x and 2.x
 # Copyright (C) 2001-2006  James Henstridge
+# Copyright (C) 2007-2008  Frederic Peters
 #
 #   autotools.py: autotools module type definitions.
 #
@@ -22,7 +23,7 @@
 import os
 import re
 
-from jhbuild.errors import FatalError, BuildStateError
+from jhbuild.errors import FatalError, BuildStateError, CommandError
 from jhbuild.modtypes import \
      Package, get_dependencies, get_branch, register_module_type
 
@@ -186,7 +187,11 @@
     def do_check(self, buildscript):
         buildscript.set_action('Checking', self)
         cmd = '%s %s check' % (os.environ.get('MAKE', 'make'), self.makeargs)
-        buildscript.execute(cmd, cwd=self.get_builddir(buildscript))
+        try:
+            buildscript.execute(cmd, cwd=self.get_builddir(buildscript))
+        except CommandError:
+            if not buildscript.config.makecheck_advisory:
+                raise
     do_check.next_state = STATE_DIST
     do_check.error_states = [STATE_FORCE_CHECKOUT, STATE_CONFIGURE]
 

Modified: trunk/jhbuild/modtypes/waf.py
==============================================================================
--- trunk/jhbuild/modtypes/waf.py	(original)
+++ trunk/jhbuild/modtypes/waf.py	Sat Jan 19 19:26:21 2008
@@ -1,6 +1,7 @@
 # jhbuild - a build script for GNOME 1.x and 2.x
-# Copyright (C) 2007  Gustavo Carneiro
 # Copyright (C) 2001-2006  James Henstridge
+# Copyright (C) 2007  Gustavo Carneiro
+# Copyright (C) 2008  Frederic Peters
 #
 #   waf.py: waf module type definitions.
 #
@@ -136,7 +137,11 @@
     def do_check(self, buildscript):
         buildscript.set_action('Checking', self)
         cmd = [self.waf_cmd, 'check']
-        buildscript.execute(cmd, cwd=self.get_builddir(buildscript))
+        try:
+            buildscript.execute(cmd, cwd=self.get_builddir(buildscript))
+        except CommandError:
+            if not buildscript.config.makecheck_advisory:
+                raise
     do_check.next_state = STATE_DIST
     do_check.error_states = [STATE_FORCE_CHECKOUT, STATE_CONFIGURE]
 

Modified: trunk/tests/mock.py
==============================================================================
--- trunk/tests/mock.py	(original)
+++ trunk/tests/mock.py	Sat Jan 19 19:26:21 2008
@@ -18,10 +18,11 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-
+import time
 
 import jhbuild.frontends.buildscript
 import jhbuild.versioncontrol
+import jhbuild.errors
 
 class Config:
     buildroot = '/tmp/'
@@ -38,20 +39,36 @@
     makecheck = False
     makedist = False
     makedistcheck = False
+    nopoison = False
+    makecheck_advisory = False
 
     prefix = '/tmp/'
 
 class PackageDB:
+    time_delta = 0
+
     def __init__(self, uptodate = False):
-        self.uptodate = uptodate
+        self.force_uptodate = uptodate
+        self.db = {}
 
     def check(self, package, version=None):
-        return self.uptodate
+        if self.force_uptodate:
+            return self.force_uptodate
+        return self.db.get(package, ('_none_'))[0] == version
 
     def add(self, package, version):
-        pass
+        self.db[package] = (version, time.time()+self.time_delta)
+
+    def remove(self, package):
+        del self.db[package]
+
+    def installdate(self, package):
+        return self.db.get(package, ('_none_'))[1]
+
 
 class BuildScript(jhbuild.frontends.buildscript.BuildScript):
+    execute_is_failure = False
+
     def __init__(self, config, module_list):
         self.config = config
         self.modulelist = module_list
@@ -59,13 +76,18 @@
         self.actions = []
     
     def set_action(self, action, module, module_num=-1, action_target=None):
-        self.actions.append(action)
+        self.actions.append('%s:%s' % (module.name, action))
 
     def execute(self, command, hint=None, cwd=None, extra_env=None):
-        pass
+        if self.execute_is_failure:
+            raise jhbuild.errors.CommandError('Mock command asked to fail')
 
     def message(self, msg, module_num = -1):
         pass
+    
+    def handle_error(self, module, state, nextstate, error, altstates):
+        self.actions[-1] = self.actions[-1] + ' [error]'
+        return 'fail'
 
 class Branch(jhbuild.versioncontrol.Branch):
     def __init__(self):
@@ -80,3 +102,6 @@
 
     def tree_id(self):
         return 'foo'
+
+def raise_command_error(*args):
+    raise jhbuild.errors.CommandError('Mock Command Error Exception')

Modified: trunk/tests/tests.py
==============================================================================
--- trunk/tests/tests.py	(original)
+++ trunk/tests/tests.py	Sat Jan 19 19:26:21 2008
@@ -28,7 +28,7 @@
 
 import jhbuild.moduleset
 from jhbuild.modtypes import Package
-from jhbuild.errors import DependencyCycleError, UsageError
+from jhbuild.errors import DependencyCycleError, UsageError, CommandError
 
 import mock
 
@@ -134,72 +134,104 @@
         self.assertEqual(self.get_module_list(['foo']), ['baz', 'bar', 'quux', 'qux', 'foo'])
 
 
-class ModTypeTestCase(unittest.TestCase):
+class BuildTestCase(unittest.TestCase):
     def setUp(self):
         self.config = mock.Config()
         self.branch = mock.Branch()
         self.branch.config = self.config
+        self.buildscript = None
 
     def build(self, packagedb_params = {}, **kwargs):
         for k in kwargs:
             setattr(self.config, k, kwargs[k])
-        buildscript = mock.BuildScript(self.config, [self.module])
-        buildscript.packagedb = mock.PackageDB(**packagedb_params)
-        buildscript.build()
-        return buildscript.actions
 
+        if not self.buildscript or packagedb_params:
+            self.buildscript = mock.BuildScript(self.config, self.modules)
+            self.buildscript.packagedb = mock.PackageDB(**packagedb_params)
+        else:
+            packagedb = self.buildscript.packagedb
+            self.buildscript = mock.BuildScript(self.config, self.modules)
+            self.buildscript.packagedb = packagedb
 
-class AutotoolsModTypeTestCase(ModTypeTestCase):
+        self.buildscript.build()
+        return self.buildscript.actions
+
+    def tearDown(self):
+        self.buildscript = None
+
+
+class AutotoolsModTypeTestCase(BuildTestCase):
     '''Autotools steps'''
 
     def setUp(self):
-        ModTypeTestCase.setUp(self)
+        BuildTestCase.setUp(self)
         from jhbuild.modtypes.autotools import AutogenModule
-        self.module = AutogenModule('foo', self.branch)
+        self.modules = [AutogenModule('foo', self.branch)]
 
     def test_build(self):
         '''Building a autotools module'''
         self.assertEqual(self.build(),
-                ['Checking out', 'Configuring', 'Building', 'Installing'])
+                ['foo:Checking out', 'foo:Configuring', 'foo:Building',
+                 'foo:Installing'])
 
     def test_build_no_network(self):
         '''Building a autotools module, without network'''
         self.assertEqual(self.build(nonetwork = True),
-                ['Configuring', 'Building', 'Installing'])
+                ['foo:Configuring', 'foo:Building', 'foo:Installing'])
 
     def test_update(self):
         '''Updating a autotools module'''
-        self.assertEqual(self.build(nobuild = True), ['Checking out'])
+        self.assertEqual(self.build(nobuild = True), ['foo:Checking out'])
 
     def test_build_check(self):
         '''Building a autotools module, with checks'''
         self.assertEqual(self.build(makecheck = True),
-                ['Checking out', 'Configuring', 'Building', 'Checking', 'Installing'])
+                ['foo:Checking out', 'foo:Configuring', 'foo:Building',
+                 'foo:Checking', 'foo:Installing'])
 
     def test_build_clean_and_check(self):
         '''Building a autotools module, with cleaning and checks'''
         self.assertEqual(self.build(makecheck = True, makeclean = True),
-                ['Checking out', 'Configuring', 'Cleaning', 'Building', 'Checking', 'Installing'])
+                ['foo:Checking out', 'foo:Configuring', 'foo:Cleaning',
+                 'foo:Building', 'foo:Checking', 'foo:Installing'])
+
+    def test_build_check_error(self):
+        '''Building a autotools module, with an error in make check'''
+
+        def make_check_error(buildscript, *args):
+            self.modules[0].do_check_orig(buildscript, *args)
+            raise CommandError('Mock Command Error Exception')
+        make_check_error.next_state = self.modules[0].do_check.next_state
+        make_check_error.error_states = self.modules[0].do_check.error_states
+        self.modules[0].do_check_orig = self.modules[0].do_check
+        self.modules[0].do_check = make_check_error
+
+        self.assertEqual(self.build(makecheck = True),
+                ['foo:Checking out', 'foo:Configuring', 'foo:Building',
+                 'foo:Checking [error]'])
 
 
-class BuildPolicyTestCase(ModTypeTestCase):
+
+class BuildPolicyTestCase(BuildTestCase):
     '''Build Policy'''
 
     def setUp(self):
-        ModTypeTestCase.setUp(self)
+        BuildTestCase.setUp(self)
         from jhbuild.modtypes.autotools import AutogenModule
-        self.module = AutogenModule('foo', self.branch)
+        self.modules = [AutogenModule('foo', self.branch)]
 
     def test_policy_all(self):
         '''Building an uptodate module with build policy set to "all"'''
         self.config.build_policy = 'all'
         self.assertEqual(self.build(packagedb_params = {'uptodate': True}),
-                ['Checking out', 'Configuring', 'Building', 'Installing'])
+                ['foo:Checking out', 'foo:Configuring', 'foo:Building',
+                 'foo:Installing'])
 
     def test_policy_updated(self):
         '''Building an uptodate module with build policy set to "updated"'''
         self.config.build_policy = 'updated'
-        self.assertEqual(self.build(packagedb_params = {'uptodate': True}), ['Checking out'])
+        self.assertEqual(self.build(packagedb_params = {'uptodate': True}),
+                ['foo:Checking out'])
 
     def test_policy_all_with_no_network(self):
         '''Building an uptodate module with "all" policy, without network'''
@@ -207,7 +239,7 @@
         self.assertEqual(self.build(
                     packagedb_params = {'uptodate': True},
                     nonetwork = True),
-                ['Configuring', 'Building', 'Installing'])
+                ['foo:Configuring', 'foo:Building', 'foo:Installing'])
 
     def test_policy_updated_with_no_network(self):
         '''Building an uptodate module with "updated" policy, without network'''
@@ -217,22 +249,167 @@
                     nonetwork = True), [])
 
 
-class TestModTypeTestCase(ModTypeTestCase):
+class TestModTypeTestCase(BuildTestCase):
     '''Tests Module Steps'''
 
     def setUp(self):
-        ModTypeTestCase.setUp(self)
+        BuildTestCase.setUp(self)
         from jhbuild.modtypes.testmodule import TestModule
-        self.module = TestModule('foo', self.branch, 'dogtail')
+        self.modules = [TestModule('foo', self.branch, 'dogtail')]
 
     def test_run(self):
         '''Running a test module'''
-        self.assertEqual(self.build(), ['Checking out', 'Testing'])
+        self.assertEqual(self.build(), ['foo:Checking out', 'foo:Testing'])
 
     def test_build_no_network(self):
         '''Running a test module, without network'''
-        self.assertEqual(self.build(nonetwork = True), ['Testing'])
+        self.assertEqual(self.build(nonetwork = True), ['foo:Testing'])
+
+
+class TwoModulesTestCase(BuildTestCase):
+    '''Building two dependent modules'''
+
+    def setUp(self):
+        BuildTestCase.setUp(self)
+        from jhbuild.modtypes.autotools import AutogenModule
+        self.foo_branch = mock.Branch()
+        self.modules = [AutogenModule('foo', self.foo_branch),
+                        AutogenModule('bar', self.branch)]
+
+    def test_build(self):
+        '''Building two autotools module'''
+        self.assertEqual(self.build(),
+                ['foo:Checking out', 'foo:Configuring',
+                 'foo:Building', 'foo:Installing',
+                 'bar:Checking out', 'bar:Configuring',
+                 'bar:Building', 'bar:Installing',
+                ])
+
+    def test_build_failure_independent_modules(self):
+        '''Building two independent autotools modules, with failure in first'''
+
+        def build_error(buildscript, *args):
+            self.modules[0].do_build_orig(buildscript, *args)
+            raise CommandError('Mock Command Error Exception')
+        build_error.next_state = self.modules[0].do_build.next_state
+        build_error.error_states = self.modules[0].do_build.error_states
+        self.modules[0].do_build_orig = self.modules[0].do_build
+        self.modules[0].do_build = build_error
+
+        self.assertEqual(self.build(),
+                ['foo:Checking out', 'foo:Configuring', 'foo:Building [error]',
+                 'bar:Checking out', 'bar:Configuring',
+                 'bar:Building', 'bar:Installing',
+                ])
+
+    def test_build_failure_dependent_modules(self):
+        '''Building two dependent autotools modules, with failure in first'''
+        self.modules[1].dependencies = ['foo']
+
+        def build_error(buildscript, *args):
+            self.modules[0].do_build_orig(buildscript, *args)
+            raise CommandError('Mock Command Error Exception')
+        build_error.next_state = self.modules[0].do_build.next_state
+        build_error.error_states = self.modules[0].do_build.error_states
+        self.modules[0].do_build_orig = self.modules[0].do_build
+        self.modules[0].do_build = build_error
+
+        self.assertEqual(self.build(),
+                ['foo:Checking out', 'foo:Configuring', 'foo:Building [error]'])
+
+    def test_build_failure_dependent_modules_nopoison(self):
+        '''Building two dependent autotools modules, with failure, but nopoison'''
+        self.modules[1].dependencies = ['foo']
+
+        def build_error(buildscript, *args):
+            self.modules[0].do_build_orig(buildscript, *args)
+            raise CommandError('Mock Command Error Exception')
+        build_error.next_state = self.modules[0].do_build.next_state
+        build_error.error_states = self.modules[0].do_build.error_states
+        self.modules[0].do_build_orig = self.modules[0].do_build
+        self.modules[0].do_build = build_error
+
+        self.assertEqual(self.build(nopoison = True),
+                ['foo:Checking out', 'foo:Configuring', 'foo:Building [error]',
+                 'bar:Checking out', 'bar:Configuring',
+                 'bar:Building', 'bar:Installing',
+                ])
+
+    def test_build_no_update(self):
+        '''Building two uptodate, autotools module'''
+        self.build() # will feed PackageDB
+        self.assertEqual(self.build(),
+                ['foo:Checking out', 'foo:Configuring',
+                 'foo:Building', 'foo:Installing',
+                 'bar:Checking out', 'bar:Configuring',
+                 'bar:Building', 'bar:Installing',
+                ])
+
+    def test_build_no_update_updated_policy(self):
+        '''Building two uptodate, autotools module, with 'updated' policy'''
+        self.build() # will feed PackageDB
+        self.assertEqual(self.build(build_policy = 'updated'),
+                ['foo:Checking out', 'bar:Checking out'])
+
+    def test_build_no_update_updated_deps_policy(self):
+        '''Building two autotools module, (changed and not), with 'updated-deps' policy'''
+        self.modules[1].dependencies = ['foo']
+        self.build() # will feed PackageDB
+        self.buildscript.packagedb.remove('foo')
+        self.buildscript.packagedb.time_delta = 5
+        self.assertEqual(self.build(build_policy = 'updated-deps'),
+                ['foo:Checking out', 'foo:Configuring',
+                 'foo:Building', 'foo:Installing',
+                 'bar:Checking out', 'bar:Configuring',
+                 'bar:Building', 'bar:Installing',
+                ])
+
+    def test_build_no_update_updated_deps_policy(self):
+        '''Building two independent autotools module, (changed and not), with 'updated-deps' policy'''
+        self.build() # will feed PackageDB
+        self.buildscript.packagedb.remove('foo')
+        self.buildscript.packagedb.time_delta = 5
+        self.assertEqual(self.build(build_policy = 'updated-deps'),
+                ['foo:Checking out', 'foo:Configuring',
+                 'foo:Building', 'foo:Installing',
+                 'bar:Checking out',])
+
+    def test_make_check_failure_dependent_modules(self):
+        '''Building two dependent autotools modules, with failure in make check'''
+        self.modules[1].dependencies = ['foo']
+
+        def check_error(buildscript, *args):
+            self.modules[0].do_check_orig(buildscript, *args)
+            raise CommandError('Mock Command Error Exception')
+        check_error.next_state = self.modules[0].do_check.next_state
+        check_error.error_states = self.modules[0].do_check.error_states
+        self.modules[0].do_check_orig = self.modules[0].do_check
+        self.modules[0].do_check = check_error
+
+        self.assertEqual(self.build(makecheck = True),
+                ['foo:Checking out', 'foo:Configuring',
+                 'foo:Building', 'foo:Checking [error]'])
 
+    def test_make_check_failure_dependent_modules_makecheck_advisory(self):
+        '''Building two dependent autotools modules, with *advisory* failure in make check'''
+        self.modules[1].dependencies = ['foo']
+
+        def check_error(buildscript, *args):
+            buildscript.execute_is_failure = True
+            try:
+                self.modules[0].do_check_orig(buildscript, *args)
+            finally:
+                buildscript.execute_is_failure = False
+        check_error.next_state = self.modules[0].do_check.next_state
+        check_error.error_states = self.modules[0].do_check.error_states
+        self.modules[0].do_check_orig = self.modules[0].do_check
+        self.modules[0].do_check = check_error
+
+        self.assertEqual(self.build(makecheck = True, makecheck_advisory = True),
+                ['foo:Checking out', 'foo:Configuring',
+                 'foo:Building', 'foo:Checking', 'foo:Installing',
+                 'bar:Checking out', 'bar:Configuring',
+                 'bar:Building', 'bar:Checking', 'bar:Installing'])
 
 
 if __name__ == '__main__':



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]